从 React 钩子读取状态



>我有以下代码

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时,不会出现电子邮件错误。就像我在返回语句中没有得到最新的状态更改一样。我做错了什么?

我在评论中给了你一个提示,但似乎你忽略了它。你不应该像调用 setState 时那样直接改变状态对象,React 会将其与原始状态对象引用进行比较(感谢 Ross 在评论中指出(。由于您已经对其进行了更改,并且 React 没有找到任何更改的属性,因此您的组件不会更新useEffect因此不会调用钩子。在工作之前创建对状态对象的新引用。以下是您需要执行的操作:

取代

const newState = state;

const newState = { ...state }

首先,要存储大型对象,就像在这种情况下一样,使用 useReducer 而不是 useState

通过键入const newState = state;您将分配相同的对象,因此您将使用相同的对象。使用这样的const newState = {...state}或sth。

让我们看看下面:

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

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


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

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

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

setState认为没有任何变化,因为您每次都传递相同的state对象。每次更新时创建一个新对象:

const newState = { ...state };

相关内容

  • 没有找到相关文章

最新更新