javascript - 使用 this.setState 后反应不以正确的状态值呈现
问题描述
我正在尝试构建一个组件,该组件会自动检查输入字段中的有效电子邮件地址,然后使用setState
.
我的那部分工作正常,但我也希望它在您在空白字段上退格时删除最后一项。
我遇到的问题是,当我拼接数组中的最后一项并使用 更新它时setState
,它不会呈现新的数组值吗?
如果我将值记录在由 调用的函数中onKeyDown
,它会记录正确更新的数组值this.state.emails
。但是,渲染函数会记录旧值并且列表不会更新。
代码笔: https ://codepen.io/adamcoulombe/pen/zJxoER
class MultiEmailInput extends React.Component {
constructor(props) {
super(props)
this.state = {
emails:[]
};
}
fieldChange(e){
if (e.target.value !== ''){
if (this.validateEmail(e.target.value)===true){
this.setState({emails: this.state.emails.concat(e.target.value)});
}
}
}
fieldKeyDown(e){
// console.log(e.target.value);
if(e.target.value===''){
var key = e.keyCode || e.charCode;
if (key == 8 || key == 46) {
this.setState({ emails: this.state.emails.splice(-1) });
//logs correct updated value
console.log(this.state.emails);
}
}
}
validateEmail(email) {
var re = /^(([^<>()\[\]\\.,;:\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,}))$/;
return re.test(String(email).toLowerCase());
}
render() {
//this value doesnt get updated?
console.log(this.state.emails);
return (
<div className={"email-multi-input"+this.props.className}>
<ul className="added-emails" ref="email-multi-input-added-emails">
{
this.state.emails.map((email, i) => {
return (<li key={i}>{email}</li>)
})}
</ul>
<input ref="email-multi-input-field" onChange={this.fieldChange.bind(this)} onKeyDown={this.fieldKeyDown.bind(this)} />
</div>
);
}
}
React.render(
<MultiEmailInput />,
document.body
);
解决方案
问题在于这一行fieldKeyDown
:
this.setState({ emails: this.state.emails.splice(-1) });
该splice
方法改变数组this.state.emails
并删除最后一个元素,但是它返回最后一个元素。所以上面的那一行this.state.emails
等于 的最后一个元素this.state.emails
。
console.log(this.state.emails)
调用时看到正确值的原因是,由于 React 不会立即更新状态(请参阅状态更新可能是异步的) ,因此尚未发生fieldKeyDown
效果。因此,您正在查看已变异的 old 。当您进入时,您会看到新值,因为在状态更新后调用。this.setState
this.state.emails
console.log
render
render
附加说明:您不应直接更改状态(即使用splice
),而应仅使用更改状态setState
。对于这个问题,您可以设置this.state.emails
等于 a slice
of this.state.emails
。这是一个例子:
this.setState({ emails: this.state.emails.slice(0, -1) });
推荐阅读
- python - 如何将字典的特定属性设置为 []
- mysql - 在链接的 MySQL 服务器中查询 6 个表中的 3 个时出错
- c# - 将一系列图像引用添加到数组
- python - python代码在python shell上工作正常,但在导入py2neo时不能通过cmd
- sql - Reporting Services 本地使用情况跟踪
- ruby-on-rails - 查看助手以删除视图中的插入类对象
- android-gradle-plugin - gradlew 在哪里寻找 Android SDK?
- vb.net - 基本日期时间代数
- apache-kafka - 重新键入主题对 Kafka 消费者的性能有何影响?
- python - 使用 Python 更新 DynamoDB 中的项目中的子项目