从React钩子读取状态

时间:2019-07-24 13:45:21

标签: javascript reactjs react-hooks

我有以下代码

const initialState = {
    values: {
        email: '',
        password: ''
    },
    touched: {
        email: false,
        password: false
    },
    errors: false,
    isValid: false,
    isLoading: false,
    submitError: null
};

function SignIn(props) {
    const [state, setState] = useState(initialState);

    useEffect(() => {
        console.log(state);
    });

    const handleFieldChange = (field, value) => {
        const newState = state;

        newState.submitError = null;
        newState.touched[field] = true;
        newState.values[field] = value;

        newState.errors = true; // set to true just for test

        setState(newState);

    };

    const showEmailError = state.errors.email;


    return (
        <div>
        <TextField
            className={classes.textField}
            label="Email address"
            name="email"
            onChange={event => handleFieldChange('email', event.target.value)}
            type="text"
            value={state.email}
            variant="outlined"

        />

        {showEmailError && (
            <Typography
                className={classes.fieldError}
                variant="body2"
            >
                {state.errors.email[0]}
            </Typography>
        )}
        </div>
    )
    }

我的问题是执行handFieldChange时,不会出现电子邮件错误。就像我在return语句中没有得到最新的状态更改一样。我在做什么错了?

3 个答案:

答案 0 :(得分:2)

我在注释中给了您提示,但好像您忽略了它。您不应像在调用setState时那样直接改变状态对象,React会将其与原始状态对象引用进行比较(感谢Ross在注释中指出)。由于您已经对其进行了突变并且React无法找到任何更改的属性,因此您的组件不会更新,因此不会调用useEffect钩子。在工作之前,请创建对状态对象的新引用。这是您需要做的:

替换

const newState = state;

const newState = { ...state }

答案 1 :(得分:-1)

首先,要存储大对象(如本例所示),请使用useReducer而不是useState

通过键入const newState = state;,您将分配相同的对象,因此您将使用仍然相同的对象。使用const newState = {...state}或类似的方式。

下面让我们看看:

const showEmailError = state.errors.email;
[...]
{state.errors.email[0]}

您的state.errors属性为布尔值,因此它没有任何嵌套对象。


在useEffect中,您需要传递依赖项数组,该数组将被跟踪并在发生任何更改时调用函数。要只调用一次,请传递空数组:

useEffect(() => {
    console.log(state);
}, []);

如果您想记录每个状态更改,请将状态作为依赖项传递。

答案 2 :(得分:-1)

q = urllib.parse.quote_plus(s) => 'Marta+Ga%C5%82szewska' 认为没有任何变化,因为您每次都将同一个setState对象传递给它。在每次更新时创建一个新对象:

state