所以我在我的 React 应用程序中遇到了一个问题,我遇到了一个特定的情况,我需要setState()
在一个方法中进行多次调用,然后在设置状态后让代码运行。下面的代码是一个用于在网站上添加帐户的对话框。
import React from 'react';
import Dialog from 'material-ui/Dialog';
import FlatButton from 'material-ui/FlatButton';
import TextField from 'material-ui/TextField';
/**
* A modal dialog can only be closed by selecting one of the actions.
*/
export default class NewAcctDia extends React.Component {
constructor(props) {
super(props);
this.state = {
open: false,
userError: null,
passError: null,
passConfirmError: null,
}
this.handleOpen = this.handleOpen.bind(this);
this.handleClose = this.handleClose.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleOpen() {
this.setState({open: true});
}
handleClose() {
this.setState({open: false});
}
handleSubmit() {
if(!this.refs.user.getValue())
this.setState({userError: "This field is required"});
else
this.setState({userError: null});
if(!this.refs.pass.getValue())
this.setState({passError: "This field is required"});
else
this.setState({passError: null});
if(this.refs.pass.getValue() == this.refs.passConfirm.getValue()) {
this.setState({passError: null});
} else {
this.setState({passConfirmError: "Passwords do not match"});
}
if(!this.state.userError && !this.state.passError && !this.state.passConfirmError)
alert('worked');
}
render() {
const actions = [
<FlatButton
label="Cancel"
primary={true}
onTouchTap={this.handleClose}
/>,
<FlatButton
label="Submit"
primary={true}
disabled={false}
onTouchTap={this.handleSubmit}
/>,
];
return (
<Dialog
title="Create an Account"
actions={actions}
modal={true}
open={this.state.open}
contentStyle={{width: 350}}
>
<TextField
ref='user'
floatingLabelText="Username"
errorText={this.state.userError}
/><br />
<TextField
ref='pass'
floatingLabelText="Password"
type="password"
errorText={this.state.passError}
/><br />
<TextField
ref='passConfirm'
floatingLabelText="Confirm Password"
type="password"
errorText={this.state.passConfirmError}
/><br />
</Dialog>
);
}
}
问题出在handleSubmit()
方法上,我需要检查用户是否在用户名和密码字段中输入了某些内容,并且密码和确认密码字段是否匹配。如果他们没有,我会在需要通过状态更改的字段中添加错误文本。然后我尝试查看状态以查看是否有任何错误。
不幸的是,正如我很快发现的那样,该setState()
函数是异步的,这意味着在我最终检查之前状态不会改变。我在谷歌上搜索并搜索了一种在执行代码之前等待状态改变的方法,但结果是空的。我现在已经解决了这个问题,并认为我会把它放在 Stack 上,这样其他人可能会从我提出的方法中受益。我还想知道我正在做的任何利弊,或者任何可能会更好的建议。
当我四处搜索时,我发现了一种发送回调的方法,setState()
如图所示:setState(data, callback)
. 起初我不认为这对我有用,因为我有多个setState()
电话。但是,我意识到我可以将该handleSubmit()
方法转换为使用三元组的单个setState()
调用。像这样:
handleSubmit() {
this.setState({
userError: (
this.refs.user.getValue() ? null : "This field is required"
),
passError: (
this.refs.pass.getValue() ? null : "This field is required"
),
passConfirmError: (
(this.refs.pass.getValue() == this.refs.passConfirm.getValue()) ?
null : "Passwords do not match"
)
}, () => {
if(!this.state.userError && !this.state.passError && !this.state.passConfirmError)
alert('worked');
})
}
匿名回调函数将在状态更改后执行,让我的检查工作。
我预见到这种方法的唯一问题是嵌套三元组,因为如果需要它们可能会变得非常混乱。这可能对我的程序有任何不利影响吗?或者我可以解决这个问题的更好方法?
我希望我的解决方案帮助了一些人。:D