我知道这个问题已经被回答过很多次了。我只是找不到解决我问题的答案,使我相信我要么很愚蠢,要么我的问题没有出现过,因为它比我还要愚蠢。
因此,除此之外,这是我的问题:

我正在尝试创建一个功能组件,该组件从redux状态获取一些信息,以便将正确的语言标签呈现为登录表单。

让我们从代码开始:

import React, { useState, useEffect } from "react";
import { Paper, TextField } from "@material-ui/core";
import { changeLanguage } from "../redux/actions";
import { useDispatch, useSelector } from "react-redux";



const Login = () => {
    const dispatch = useDispatch();
    const [language, setLanguage] = useState("de");
    const [strings, setStrings] = useState({});

    useEffect(() => {
        console.log("I have been called", language, strings);
        setLanguage(["de", "en"].includes(navigator.language.split("-")[0]) ? navigator.language.split("-")[0] : "de");
    }, [language]);

    dispatch(changeLanguage(language));
    const str = useSelector(state => state.base.strings.login);
    console.log(str);
    setStrings(str); // <- THIS ONE IS CAUSING THE ERROR
    return (
        <div className={"App"}>
            <Paper>
                <TextField label={strings.username}/><br/>
                <TextField label={strings.password} type={"password"}/>
            </Paper>
        </div>
    );
};

export default Login;


这就是我用来使应用程序完全正常运行的东西。我意识到在每个渲染器上设置字符串都会导致无限循环。那很清楚。但是,使用此代码时:

import React, { useState, useEffect } from "react";
import { Paper, TextField } from "@material-ui/core";
import { changeLanguage } from "../redux/actions";
import { useDispatch, useSelector } from "react-redux";



const Login = () => {
    const dispatch = useDispatch();
    const [language, setLanguage] = useState("de");
    const [strings, setStrings] = useState({});

    useEffect(() => {
        console.log("I have been called", language, strings);
        setLanguage(["de", "en"].includes(navigator.language.split("-")[0]) ? navigator.language.split("-")[0] : "de");
        dispatch(changeLanguage(language));
        const str = useSelector(state => state.base.strings.login);
        console.log(str);
        setStrings(str);
    }, [language]);

    return (
        <div className={"App"}>
            <Paper>
                <TextField label={strings.username}/><br/>
                <TextField label={strings.password} type={"password"}/>
            </Paper>
        </div>
    );
};

export default Login;


我收到此错误:

/src/App/pages/login.js
  Line 17:15:  React Hook "useSelector" cannot be called inside a callback. React Hooks must be called in a React function component or a custom React Hook function  react-hooks/rules-of-hooks

Search for the keywords to learn more about each error.


是的,我确实知道它在告诉我什么,但我确实相信useEffect是一个React Hook,还是我在这里错过了一些东西?

我只是在寻找一种使它起作用的方法。可以不难,因为我可以使其与类组件一起正常工作。

如果问题很愚蠢,请详细说明原因,而不是仅仅予以否决。这将有助于发展和理解该问题。
我已经咨询了两个小时的文档,并尝试了很多东西。没事。

感谢您抽出宝贵的时间!

最佳答案

 useEffect(() => {
        console.log("I have been called", language, strings);
        setLanguage(["de", "en"].includes(navigator.language.split("-")[0]) ? navigator.language.split("-")[0] : "de");
        dispatch(changeLanguage(language));
        const str = useSelector(state => state.base.strings.login);
        console.log(str);
        setStrings(str);
    }, [language]);


您正在另一个内部使用一个钩子,这是不允许的。只能将钩子放置在功能组件内部以及任何方法之外。有关更多信息,请参见https://reactjs.org/docs/hooks-rules.html

关于javascript - Redux-Hooks:将React Hooks与Redux Hooks结合使用,可以创建无限循环或什么都不做,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60476938/

10-15 13:17