【问题标题】:concat vs push in react jsconcat vs push in react js
【发布时间】:2018-03-09 15:11:03
【问题描述】:

我对 React 还是很陌生。我不明白为什么这个问题不起作用。 我有Numbers Component。

const Numbers = (props) => {
  return(
    <div className="card text-center">
        <div>
        {Numbers.list.map((num,i) => 
            <span key={i} onClick={() => props.selectNumbers(num)}>
            {num}
          </span>
        )}
      </div>
    </div>
  );
}

Numbers.list = [1,2,3,4,5,6,7,8,9];

现在在父 Game 组件中..

class Game extends React.Component {

    state = {
    selectedNumbers : []
  };

  selectNumber = (clickedNumber) => {
    if(this.state.selectedNumbers.indexOf(clickedNumber) >= 0) {return;}
    this.setState(prevState => ({
        selectedNumbers: prevState.selectedNumbers.concat(clickedNumber)
    }));
  };


    render() {
    const {selectedNumbers } = this.state;
    return (
        <div className="container">
        <h3>
            Play Nine
        </h3>
        <hr />
        <div className="row">
          <Answer selectedNums = {selectedNumbers} />
        </div>
        <br />
        <Numbers selectNumbers={this.selectNumber} selectedNums = {selectedNumbers} />
      </div>
    );
  }
}

现在,这东西很好用。但是当我这样做时......

this.setState(prevState => ({
        selectedNumbers: prevState.selectedNumbers.push(clickedNumber)
    }));

应用程序按预期工作。

As prevState.selectedNumbers is an array 不应该是push 而不是concat? 我做错了什么?

【问题讨论】:

  • push 是一个变异操作。所以在前一个状态上调用 push 会尝试改变它。这就像试图改变历史。你想要做的是通过重用旧状态而不改变它来创建一个新状态。这就是你可以用 concat 或 ES6 扩展运算符来做的事情。

标签: javascript arrays reactjs


【解决方案1】:

简而言之:

Array.prototype.push() 将一个元素添加到原始数组中并返回一个 整数,这是它的新数组 length。

Array.prototype.concat() 返回一个带有连接元素的新数组,甚至没有触及原始数组。这是一个浅拷贝。

【讨论】:

    【解决方案2】:

    当你使用push时,你将selectedNumbers设置为push操作的返回值,即根据mozilla developer docs新数组的长度。 Push 还尝试在 state 中改变数组,正如 PhilippSpo 所说,这不起作用。

    要么像以前一样使用concat,要么将selectedNumbers复制到一个新数组中,将你的值推送到那个数组中,然后将selectedNumbers设置为新数组。如果您使用的是 ES6,则可以像其他用户指出的那样使用扩展运算符

    【讨论】:

      【解决方案3】:

      如 cmets 中所述,push 是一个变异函数,并返回结果数组的长度。您可以使用spread syntax 轻松推送新项目。

      this.setState(prevState => ({
              selectedNumbers: [...prevState.selectedNumbers, clickedNumber]
          }));
      

      【讨论】:

        【解决方案4】:

        你应该使用 concat() 函数代替 push() 因为 react 不能很好地处理对象的可变性 react 人们强调 react 开发人员要保持不可变的状态.

        当你使用 concat() 函数时,它总是返回一个新对象而不是改变同一个旧对象,这就是为什么你不应该在反应中使用 push() 函数因为 push 会改变旧对象。

        【讨论】:

          猜你喜欢
          • 2014-10-09
          • 2017-11-18
          • 2018-04-26
          • 1970-01-01
          • 2014-09-13
          • 1970-01-01
          • 2022-12-26
          • 2016-11-22
          相关资源
          最近更新 更多