我想在state
数组的末尾添加一个元素,这是正确的方法吗?
this.state.arrayvar.push(newelement);
this.setState({ arrayvar:this.state.arrayvar });
我担心就地修改数组push
可能会导致麻烦 - 安全吗?
制作数组副本的替代方法,而setState
ing 似乎很浪费。
我想在state
数组的末尾添加一个元素,这是正确的方法吗?
this.state.arrayvar.push(newelement);
this.setState({ arrayvar:this.state.arrayvar });
我担心就地修改数组push
可能会导致麻烦 - 安全吗?
制作数组副本的替代方法,而setState
ing 似乎很浪费。
该阵营的文档说:
将 this.state 视为不可变的。
您push
将直接改变状态,这可能会导致容易出错的代码,即使您之后再次“重置”状态。F.ex,它可能导致某些生命周期方法componentDidUpdate
不会触发。
在更高版本的 React 中推荐的方法是在修改状态时使用更新程序函数来防止竞争条件:
this.setState(prevState => ({
arrayvar: [...prevState.arrayvar, newelement]
}))
与使用非标准状态修改可能面临的错误相比,内存“浪费”不是问题。
早期 React 版本的替代语法
您可以使用concat
获得干净的语法,因为它返回一个新数组:
this.setState({
arrayvar: this.state.arrayvar.concat([newelement])
})
在 ES6 中,您可以使用扩展运算符:
this.setState({
arrayvar: [...this.state.arrayvar, newelement]
})
最简单,如果您使用ES6
.
initialArray = [1, 2, 3];
newArray = [ ...initialArray, 4 ]; // --> [1,2,3,4]
新阵列将是 [1,2,3,4]
在React 中更新你的状态
this.setState({
arrayvar:[...this.state.arrayvar, newelement]
});
最简单的方法ES6
:
this.setState(prevState => ({
array: [...prevState.array, newElement]
}))
React 可能会批量更新,因此正确的方法是为 setState 提供一个执行更新的函数。
对于 React 更新插件,以下内容将可靠地工作:
this.setState( state => update(state, {array: {$push: [4]}}) );
或对于 concat():
this.setState( state => ({
array: state.array.concat([4])
}));
下面以https://jsbin.com/mofekakuqi/7/edit?js,output为例说明如果出错会发生什么。
setTimeout() 调用正确添加了三个项目,因为 React 不会在 setTimeout 回调中批量更新(参见https://groups.google.com/d/msg/reactjs/G6pljvpTGX0/0ihYw2zK9dEJ)。
有问题的 onClick 只会添加“Third”,但固定的会按预期添加 F、S 和 T。
class List extends React.Component {
constructor(props) {
super(props);
this.state = {
array: []
}
setTimeout(this.addSome, 500);
}
addSome = () => {
this.setState(
update(this.state, {array: {$push: ["First"]}}));
this.setState(
update(this.state, {array: {$push: ["Second"]}}));
this.setState(
update(this.state, {array: {$push: ["Third"]}}));
};
addSomeFixed = () => {
this.setState( state =>
update(state, {array: {$push: ["F"]}}));
this.setState( state =>
update(state, {array: {$push: ["S"]}}));
this.setState( state =>
update(state, {array: {$push: ["T"]}}));
};
render() {
const list = this.state.array.map((item, i) => {
return <li key={i}>{item}</li>
});
console.log(this.state);
return (
<div className='list'>
<button onClick={this.addSome}>add three</button>
<button onClick={this.addSomeFixed}>add three (fixed)</button>
<ul>
{list}
</ul>
</div>
);
}
};
ReactDOM.render(<List />, document.getElementById('app'));
正如评论中提到的@nilgun,您可以使用 react immutability helpers。我发现这非常有用。
从文档:
简单推送
var initialArray = [1, 2, 3];
var newArray = update(initialArray, {$push: [4]}); // => [1, 2, 3, 4]
initialArray 仍然是 [1, 2, 3]。