我在执行setState更改对象嵌套数组的值时遇到问题。下面的代码假设 更改ID 2的问题以回答:正确,但事实并非如此,这是怎么回事?
this.state = {
questions: [
{
id: 1,
answer: ''
},
{
id: 2,
answer: ''
},
]
}
//I have a click event somewhere
this.setState(
{
questions: this.state.questions.map(q => {
if (q.id === 2) {
return {
...q,
answer: true
}
} else {
return { ...q }
}
})
},
console.log(this.state.questions[1]) // did not see id of 2 being changed to true?
)
答案 0 :(得分:2)
在执行console.log(this.state.questions[1])
行之前先执行this.setState
行,这就是将旧状态打印到控制台的原因。您应该将行放在函数内部以延迟执行:
this.setState(..., () => console.log(this.state.questions[1]));
如果更改后的状态是从当前状态派生的,还建议使用函数作为第一个参数,因为React不会立即应用新状态,因此this.state
可能会在React应用新状态时过时:
this.setState(state => ({
questions: state.questions.map(q => {
if (q.id === 2) {
return {...q, answer: true};
}
return q;
})
}), () => {
console.log(this.state.questions[1]);
});
答案 1 :(得分:0)
您没有调用setState
回调。尝试这样:
this.setState(
{
questions: this.state.questions.map(q => {
if (q.id === 2) {
return {
...q,
answer: true
};
}
return { ...q };
})
},
() => console.log(this.state.questions[1]) // did not see id of 2 being changed to true?
);
但是,由于您正在使用当前状态来再次更新您的状态,因此最好使用功能性setState。
this.setState(
currentState => ({
questions: currentState.questions.map(q => {
if (q.id === 2) {
return {
...q,
answer: true
};
}
return { ...q };
})
}),
() => console.log(this.state.questions[1])
);
此外,您不必将状态记录在setState
的回调中。您可以在render
方法中记录状态,而不会遇到setState
的回调问题。
this.setState(
currentState => ({
questions: currentState.questions.map(q => {
if (q.id === 2) {
return {
...q,
answer: true
};
}
return { ...q };
})
})
);
....
render() {
console.log( this.state );
....
}
答案 2 :(得分:-1)
我认为这是因为Array.map返回一个数组。试试:
this.setState(
{
questions: this.state.questions.map(q => {
if (q.id === 2) {
q.answer = true;
}
return q;
})
}, console.log(this.state.questions [1])//没看到2的ID更改为true吗? )