问题更新反应中的状态

Issue updating the state in react

在我的登录组件中,我尝试验证用户输入并使用 React 状态设置错误,但我在更新 errorState.

时遇到问题

这是我的登录组件

const Login = () => {
    const [state, setState] = React.useState({email: '', password: ''});

    const initialErrorState = {emailError: '', passwordError: ''};
    const [errorState, setErrorState] = React.useState(initialErrorState);

    const handleChange = (e, {name, value}) => {
        setState({...state, [name]: value});
    }

    const validate = () => {
        const emailRegEx = /^(([^<>()[\]\.,;:\s@"]+(\.[^<>()[\]\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;

        state.email === '' ? setErrorState({...errorState, emailError: "Email is required"}) :
            !state.email.match(emailRegEx) ? setErrorState({...errorState, emailError: "Email is invalid"}) :
            setErrorState({...errorState, emailError: ''});

        state.password === '' ? setErrorState({...errorState, passwordError: 'Password is required'}) :
        setErrorState({...errorState, passwordError: ''});
    }

    const handleSubmit = (e) => {
        e.preventDefault();

        validate();
        console.log(errorState);

        if (!(JSON.stringify(errorState) === JSON.stringify(initialErrorState)))
            return;

        //  console.log(state);
    }

    return (
        <Container>
            <h1>Login</h1>
            <Form onSubmit={handleSubmit}>
                <Form.Input 
                    label="Email"
                    placeholder="example@gmail.com"
                    name="email"
                    onChange={handleChange}
                    error={errorState.emailError ? errorState.emailError : null}
                />
                <Form.Input 
                    label="Password"
                    type="password"
                    name="password"
                    onChange={handleChange}
                    error={errorState.passwordError ? errorState.passwordError : null}
                />
                <Form.Button 
                    type="submit"
                    content="Login"
                />
            </Form>
        </Container>
    );
};

调用validate()函数时不要在我的errorState中设置emailError。它只设置 passwordError。调用 validate() 函数后的控制台日志记录 errorState 给出以下内容。
故意将电子邮件和密码字段留空并多次按下登录按钮

{emailError: '', passwordError: ''}
Login.js:29 {emailError: '', passwordError: 'Password is required'}
Login.js:29 {emailError: '', passwordError: 'Password is required'}
Login.js:29 {emailError: '', passwordError: 'Password is required'}
Login.js:29 {emailError: '', passwordError: 'Password is required'}

如果我将验证函数修改为以下
将密码验证置于电子邮件验证之上

const validate = () => {
        const emailRegEx = /^(([^<>()[\]\.,;:\s@"]+(\.[^<>()[\]\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;

        state.password === '' ? setErrorState({...errorState, passwordError: 'Password is required'}) :
        setErrorState({...errorState, passwordError: ''});

        state.email === '' ? setErrorState({...errorState, emailError: "Email is required"}) :
            !state.email.match(emailRegEx) ? setErrorState({...errorState, emailError: "Email is invalid"}) :
            setErrorState({...errorState, emailError: ''});
    }

这次我的emailError设置好了,但是passwordError没有设置。调用 validate() 函数后的控制台日志记录 errorState 给出以下内容。
再次故意将电子邮件和密码字段留空并多次按下登录按钮

{emailError: '', passwordError: ''}
Login.js:29 {emailError: 'Email is required', passwordError: ''}
Login.js:29 {emailError: 'Email is required', passwordError: ''}
Login.js:29 {emailError: 'Email is required', passwordError: ''}

谁能帮我理解为什么会这样?为什么我的 errorState 对象的两个属性都没有设置?

React setState 调用被批处理和排队,状态更新 may be async。如果您尝试在设置状态后立即访问它,您将无法获得正确的值。

React may batch multiple setState() calls into a single update for performance.

Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state.

您可以使用 useEffect 钩子来监听状态变化,这将在每次依赖项变化时触发

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