更新道具后,this.props总是=== nextProps/prevProps

use*_*185 21 javascript reactjs

我在这里找到了一个关于这个问题的jsbin:http://jsbin.com/tekuluve/1/edit

在onClick事件中,我正在从模型中删除元素,并重新呈现应用程序.但奇怪的是,在componentWillReceiveProps()(以及componentWillUpdate和componentDidUpdate)中,无论我做什么,nextProps总是===到this.props.

/** @jsx React.DOM */
var Box = React.createClass({
  render: function() {
    return (
      <div className="box" onClick={ UpdateModel }>
        { this.props.label }
      </div>
    );
  }
});

var Grid = React.createClass({
  componentWillReceiveProps: function(nextProps) {      
    // WTF is going on here???
    console.log(nextProps.boxes === this.props.boxes)        
  },
  render: function() {
    var boxes = _.map(this.props.boxes, function(d) {
      return (<Box label={ d.number } />);
    });

    return (
      <div className="grid">
        { boxes }
      </div>
    );
  }
});

var model = [
  { number: 1 },
  { number: 2 },
  { number: 3 },
  { number: 4 },
  { number: 5 }
];

function UpdateModel() {
  React.renderComponent(
    <Grid boxes={ _.pull(model, _.sample(model)) } />,
    document.body
  );
}

React.renderComponent(
  <Grid boxes={ model } />,
  document.body
);
Run Code Online (Sandbox Code Playgroud)

在componentWillReceiveProps()生命周期事件中通过UpdateModel()更新后,我需要nextProps与this.props不同.

Ada*_*one 14

这样的事情发生在我身上,使用Flux Stores以官方Todo List教程(http://facebook.github.io/flux/docs/todo-list.html)建议的方式存储我的状态.对于在完成教程后发现这一点的其他人,getAll()方法中的TodoStore似乎出现了问题,因为它返回对内部数据对象的直接引用:

getAll: function() {
  return _todos;
}
Run Code Online (Sandbox Code Playgroud)

这似乎打破了生命周期方法(如componentDidUpdate(prevProps))区分旧道具和新道具的能力.我认为原因是通过将对Store的数据对象的直接引用传递到视图中,state/props在Store更改时立即有效地更改,而不是在通过生命周期方法传递新值之后立即更改,因此新旧道具总是如此包含相同的值.这可以通过传递内部数据对象_todos的副本而不是对象本身来解决,

例如,当_todos是一个对象时,

getAll: function() {
  return JSON.parse(JSON.stringify(_todos));
}
Run Code Online (Sandbox Code Playgroud)

如果_todos是一个数组,则可以使用return _todos.slice()代替.

通常,如果使用Store来包含状态信息并从控制器视图中调用它,则建议返回数据的副本而不是对原始数据的引用,因为原始状态将在状态发生变化时发生变化.


Aug*_*aas 13

===将检查它是否是同一个对象.看来你正在做的是改变boxes属性指向的值.


Fed*_*ico 10

你可以使用Immutable.js.它是Facebook与react/flux合作的一个库. https://facebook.github.io/immutable-js/

我们被这几次困扰了.

shouldComponentUpdate(nextProps) { 
    return this.props.myObj !== nextProps.myObj
}
Run Code Online (Sandbox Code Playgroud)

很多时候,myObj对象中的某些值会发生变化.但是上面的函数会返回false.原因是,既this.props.myObjnextProps.myObj被引用/指向同一个对象.

通过实现Immutable.js,数据将始终作为克隆传递(而不是引用相同的对象,它们实际上是单独的对象).

它重新强化了通量的单向流动.您永远无法(意外地)修改传递到组件中的原始数据(无论是作为道具还是来自助焊剂存储).

这也使您可以使用PureRenderMixin - 如果状态/道具的值没有改变,它会自动停止渲染.这可能有助于提高性能.