[英]React not rendering with correct state value after using this.setState
我正在嘗試構建一個組件,該組件將自動檢查輸入字段中的有效電子郵件地址,然后使用setState
將其添加到數組中。
我的那部分工作正常,但是當您在空白字段上退格時,我也希望它刪除最后一項。
我遇到的問題是,當我拼接數組中的最后一項,並使用setState
更新它時,它不會呈現新的數組值嗎?
如果將值記錄在onKeyDown
調用的函數中,它將記錄this.state.emails
的正確更新數組值。 但是,渲染功能會記錄舊值,並且列表不會更新。
Codepen: 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
。
在fieldKeyDown
調用console.log(this.state.emails)
時看到正確值的原因是,由於React不會立即更新狀態,因此this.setState
的影響尚未發生(請參閱狀態更新可能是異步的 ) 。 因此,您正在查看已this.state.emails
的舊this.state.emails
。 當您在render
console.log
,您會看到新值,因為在狀態更新后調用了render
。
補充說明:您不應直接更改狀態(即使用splice
),而應僅使用setState
更改狀態。 對於這個問題,你可以設置this.state.emails
等於slice
的this.state.emails
。 這是一個例子:
this.setState({ emails: this.state.emails.slice(0, -1) });
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.