Redux - Хуки: используя React Hooks с Redux Hooks, создай бесконечное l oop или вообще ничего - PullRequest
1 голос
/ 01 марта 2020

Я знаю, что на этот вопрос уже отвечали несколько раз. Я просто не могу найти ответ, который решает мою проблему, заставляя меня поверить, что я либо глуп, либо моей проблемы не было, потому что она еще глупее меня. Итак, кроме этого, это моя проблема:

Я пытаюсь создать функциональный компонент, который берет некоторую информацию из избыточного состояния, чтобы преобразовать метки правильного языка в форму входа в систему.

Давайте начнем с кода:

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;

Это то, что я использовал, чтобы приложение работало вообще. Я понимаю, что установка строк для каждого рендера приведет к бесконечному l oop. Это ясно. Однако при использовании этого кода:

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 или я что-то здесь упускаю?

Я просто ищу способ заставить это работать. Это не может быть так сложно, потому что я могу заставить его работать с компонентами класса без проблем.

Если вопрос глупый, уточните почему, а не просто проголосуйте. Это было бы намного более полезно в разработке и понимании этого вопроса. Я проверил документы в течение двух часов и попробовал кучу вещей. Ничего не сработало.

Спасибо, что нашли время!

1 Ответ

0 голосов
/ 01 марта 2020
 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

...