React shouldComponentUpdate没有检测到数组长度的变化?

时间:2015-12-10 07:20:43

标签: reactjs

当改变通过道具传递的数组的长度时,' shouldComponentUpdate'函数无法检测到数组长度的变化。 我知道' shouldComponentUpdate'无法检测嵌套对象属性的变化,但这是一个简单的数组长度!!这是React中的一个错误吗?

https://jsfiddle.net/ashraffayad/cLz1q8sv/

var ArrTest = React.createClass({
  render: function() {
    return <div >{this.props.arr}< /div>;
  },
  shouldComponentUpdate: function(nextProps) {
    console.log(this.props.arr.length, nextProps.arr.length); // same length !!!
    return true;
  }
});

// - - - - app component
var App = React.createClass({
  getInitialState: function() {
    return {
      arr: [1, 2, 3, 4]
    };
  },
  render: function() {
    return <ArrTest arr={ this.state.arr } />;
  },
  componentDidMount: function() {
    var self = this;
    setTimeout(function() {
      self.state.arr.push(7);
      self.setState(self.state);
    }, 2000);
  }

});

ReactDOM.render( < App /> ,
  document.getElementById('container')
);

3 个答案:

答案 0 :(得分:3)

这不是React中的错误,这是您的代码的问题。 您不应该直接修改gid=值。

试试这个:

this.state

有效。因为React在向下传递道具时不会克隆道具,因此对数组的更改会反映在它的所有引用上。

我建议你在Javascript中阅读更多有关不变性的内容。

简而言之,永远不要做 componentDidMount: function() { var self = this; setTimeout(function() { self.setState({arr: self.state.arr.concat([7])}); }, 2000); } 。 做这样的事情:

this.state.[anything].push/pop/shift/unshift()

答案 1 :(得分:1)

仅仅因为你有两个引用(this.props.arrnextProps.arr)并不意味着你有两个实例

使用push变异数组时,可以修改实例。当shouldComponentUpdate运行时,它会比较引用,因为它们指向同一个实例,所以数组长度是相同的。

如果要传递具有不同元素或属性的新数组,则还需要创建一个新数组。

push替换为concat非常容易。

setTimeout(function() {
  self.setState({
    arr: self.state.concat([7])
}, 2000);

答案 2 :(得分:1)

您在if中引用了相同的数组,即,您正在修改相同的数组而不是创建一个新数组,并且您正在shouldComponentUpdate中对同一个数组进行两次引用

You should always treat props and state as immutable因此使用.concat创建一个新数组而不是按状态推送到阵列将解决您当前的问题。

setTimeout(function () {
    this.setState({arr: this.state.concat([7])});
}.bind(this), 2000);

如果您在this.props.arr === nextProps.arr内完成shouldComponentUpdate,则会看到阵列彼此相等。