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

fns*_*jdb 9 javascript components reactjs

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

所以我componentWillReceiveProps在组件中添加了一个方法,在其中,我计算了两个总计:total从中计算this.propsnextTotal计算nextProps.

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

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

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')
  );
}
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,它每秒都向vals数组添加10 ,这意味着总数上升了1.但是如果你打开控制台,你可以看到它total并且nextTotal始终是相同的,并且moving up永远不会被记录.

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

S M*_*han 12

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

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

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

每次将一个数组的副本作为你的道具​​传递,你会看到它们的不同.

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