即使道具发生了变化,nextProps也始终与componentWillReceiveProps中的this.props相同

时间:2016-04-26 19:03:06

标签: javascript reactjs components

我的React应用中有一个组件可以为用户呈现总价值。当这个值上升时,我想发出噪音。我认为在显示总数的组件中将是一个播放噪音的好地方。

所以我在组件中添加了componentWillReceiveProps方法,在其中,我计算了两个总计:totalthis.props计算,nextTotal从{{{ 1}}。

令我惊讶的是,即使值发生变化且总计发生变化,nextPropsnextTotal 总是相同。因此,当总数上升时我想要解雇的条件永远不会发生。

我写了一个简单的单组件示例。 JSfiddle

total

正如您所看到的,它每秒都会向var Hello = React.createClass({ componentWillReceiveProps: function(nextProps) { var total = 0; this.props.vals.forEach(val => total+= val); var nextTotal = 0; nextProps.vals.forEach(val => nextTotal+= val); console.log(total, nextTotal) if (nextTotal > total) { //never runs console.log('moving up'); } }, render: function() { var total = 0; vals.forEach(val => total+= val) return ( <div>{total}</div> ) } }); var vals = [1, 21, 452, 123]; setInterval(renderReact, 1000) function renderReact() { vals.push(10); ReactDOM.render( <Hello vals={vals} />, document.getElementById('container') ); } 数组添加10,这意味着总数上升了1.但是如果您打开控制台,则可以看到vals和{{ 1}}始终相同,total永远不会被记录。

我明显误解了某些事情,如果有人能够解释我的误解是什么,以及我应该如何实现我的目标,那就太棒了。

1 个答案:

答案 0 :(得分:12)

如评论中所述(@PitaJ),您的问题是您第一次传入数组,然后更改数组 - 而不是使用新属性调用。您已进入组件所持对象的对象作为其现有属性并更改了其内容。

在你的小提琴中,试试这个:

function renderReact() {
    vals.push(10);
  ReactDOM.render(
    <Hello
      vals={vals.concat([])}
    />,
    document.getElementById('container')
  );
}

每次将阵列的副本作为你的道具​​传递,你会发现它们的位置不同。

这实际上是使用反应时的一个非常重要的错误来源,即使在使用redux时也会出现错误,如果没有仔细编写减速器。使用不可变数据结构是避免它的一种方法。