当改变通过道具传递的数组的长度时,' 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')
);
答案 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.arr
,nextProps.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
,则会看到阵列彼此相等。