问题更新反应中的状态
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])
在我的登录组件中,我尝试验证用户输入并使用 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])