ReactJS 状态被延迟修改?



我正在以编程方式验证电子邮件和密码输入以进行简单登录,这是调用其他验证电子邮件的函数的函数。

handleLogin(event) {
this.validateEmail();
this.validatePassword();
if (this.state.emailValid === 'error' || this.state.passwordValid === 'error') {
alert('invalid form');
return;
};
const email = ReactDOM.findDOMNode(this.refs.email).value;
const password = ReactDOM.findDOMNode(this.refs.password).value;
const creds = { email: email, password: password }
this.props.onLoginClick(creds)
}

请注意,首先我调用的是validateEmail()函数,该函数修改指示输入是否正确的存储,下面是validateEmail()源代码:

validateEmail() {
const email = ReactDOM.findDOMNode(this.refs.email).value;
let validEmail = /^.+([.%+-_]w+)*@w+([.-]w+)*.w+([-.]w+)*$/.test(email);
if (!validEmail) {
this.setState({
emailValid: 'error'
});
return;
}
this.setState({
emailValid: 'success'
});
}

但是在if语句中,state.emailValid尚未更新,这是状态修改的延迟,因此不显示alert()。如何正确获取更新的状态?

谢谢

这里要注意的是,setState 是异步的。在 handleLogin 方法中同步的其他所有内容完成之前,它不会更新状态。

对于 React,我喜欢尽可能多地使用状态作为单一事实来源。在上面的例子中,你有 html 元素作为事实和状态的来源。通过将组件更改为由 react 状态控制,可以在每次击键时验证表单。

表单和受控组件

首先将输入的状态保持在状态

class LoginForm extends React.Component {
constructor(props) {
super(props);
this.state = {
email: '',
emailValid: true,
};
// we bind the function in case we want to 
// control text in child component
this.emailChange = this.handleEmailChange.bind(this);
}
emailChange(event) {
this.setState({email: event.target.value});
}
render() {
<textarea value={this.state.email} onChange={this.emailChange} /> 
}
}

现在,每当您键入 html 输入的状态时,都会在 react 中处理。这将使您能够更轻松地检查其有效性。我们可以通过向类中添加另一个方法来做到这一点:

class LoginForm extends React.Component {
// ...all the stuff from above
validateEmail() {
let validEmail = /^.+([.%+-_]w+)*@w+([.-]w+)*.w+([-.]w+)*$/.test(email);
if (!validEmail) {
// Object.assign just ensures immutability
this.setState(Object.assign({}, this.state, {
emailValid: false
}))
} else {
// If using babel, this is ensure immutable also
this.setState({
...state,
emailValid: true
})
}
}
// or....
validateEmail() {
let validEmail = /^.+([.%+-_]w+)*@w+([.-]w+)*.w+([-.]w+)*$/.test(email);
this.setState({...state, emailValid: validEmail})
}
// ...render method
}

现在,验证将在每次击键时进行。当您需要提交表单时,您需要做的就是检查状态是否有效并且不需要引用 dom。您可以从状态发送数据。

最新更新