首页 文章

在ReactJS中正确修改状态数组

提问于
浏览
271

我想在 state 数组的末尾添加一个元素,这是正确的方法吗?

this.state.arrayvar.push(newelement);
this.setState({arrayvar:this.state.arrayvar});

我担心用 push 就地修改数组可能会引起麻烦 - 这样安全吗?

制作数组副本的替代方案,这似乎很浪费 .

6 回答

  • 0

    React docs说:

    将this.state视为不可变的 .

    您的 push 将直接改变状态,这可能会导致容易出错的代码,即使您之后又再次处于状态"resetting" . F.ex,它可能会导致像 componentDidUpdate 这样的生命周期方法不会触发 .

    后来的React版本中推荐的方法是在修改状态时使用更新程序功能以防止竞争条件:

    this.setState(prevState => ({
      arrayvar: [...prevState.arrayvar, newelement]
    }))
    

    与使用非标准状态修改可能遇到的错误相比,内存“浪费”不是问题 .

    Alternative syntax for earlier React versions

    您可以使用 concat 获取干净的语法,因为它返回一个新数组:

    this.setState({ 
      arrayvar: this.state.arrayvar.concat([newelement])
    })
    

    在ES6中,您可以使用Spread Operator

    this.setState({
      arrayvar: [...this.state.arrayvar, newelement]
    })
    
  • 20

    最简单的,如果你使用 ES6 .

    initialArray = [1, 2, 3];
    
    newArray = [ ...initialArray, 4 ]; // --> [1,2,3,4]
    

    新阵列将 [1,2,3,4]

    React 更新您的州

    this.setState({arrayvar:[...this.state.arrayvar, newelement]});
    

    Learn more about array destructuring

  • 101

    使用 ES6 的最简单方法:

    this.setState(prevState => ({
        array: [...prevState.array, newElement]
    }))
    
  • 521

    React可以批量更新,因此正确的方法是为setState提供执行更新的函数 .

    对于React更新插件,以下内容将可靠地工作:

    this.setState( (state) => update(state, {array: {$push: [4]}}) );
    

    或者用于concat():

    this.setState( (state) => {
        state.array = state.array.concat([4]);
        return state;
    });
    

    以下显示https://jsbin.com/mofekakuqi/7/edit?js,output作为如果你弄错了会发生什么的一个例子 .

    setTimeout()调用正确地添加了三个项目,因为React不会在setTimeout回调中批量更新(请参阅https://groups.google.com/d/msg/reactjs/G6pljvpTGX0/0ihYw2zK9dEJ) .

    越野车onClick将只添加“第三”,但固定的,将按预期添加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'));
    
  • 41

    正如@nilgun在评论中提到的,你可以使用react immutability helpers . 我发现这是非常有用的 .

    来自文档:

    Simple push

    var initialArray = [1, 2, 3];
    var newArray = update(initialArray, {$push: [4]}); // => [1, 2, 3, 4]
    

    initialArray仍然是[1,2,3] .

  • 17

    这段代码对我有用:

    fetch('http://localhost:8080')
      .then(response => response.json())
      .then(json => {
        this.setState({mystate: this.state.mystate.push.apply(this.state.mystate, json)})
      })
    

相关问题