在ReactJS中更新道具

时间:2016-03-03 17:15:34

标签: reactjs

SO中的一些帖子与无法在ReactJS中更新道具有关。例如。 this one

在引用的帖子中,给出了解释,这是ReactJS哲学的一部分,有助于调试等。另外this answer(在同一个线程中)显示它是如何在ReactJS中完成的(通过使用{{1 }})。

我是ReactJS新手,所以把这个小例子放在一起,试着看看当一个人试图修改道具时会发生什么(也在jsfiddle中)

Object.freeze

我确信上述代码违反了许多良好做法,但显然很容易修改<!doctype html> <html> <body> <div id='react-app'></div> <script src="https://cdn.jsdelivr.net/react/0.14.0-rc1/react.js"></script> <script src="https://cdn.jsdelivr.net/react/0.14.0-rc1/react-dom.js"></script> <script type='text/javascript'> var rce = React.createElement.bind(React); var TodoList = React.createClass({ propTypes: { todos: React.PropTypes.arrayOf(React.PropTypes.string).isRequired, }, render: function() { var props = this.props; var todos = this.props.todos; var self = this; return rce('div', {} ,rce('ul', {} , (function(){ return todos.map(function(x, i) { return rce('li', {key: i}, x); });})()) ,rce('button', {onClick: function() { // delete props.todos; // fails // props.todos = []; // fails todos.splice(0, todos.length); // succeeds console.log(todos); self.forceUpdate(); }}, 'clear all')); } }); var todoList = rce(TodoList, {todos: ['walk dog', 'feed cat', 'water flowers']}); ReactDOM.render(todoList, document.getElementById('react-app')); </script> </body> </html> 。我理解这是因为propsObject.freeze对象上调用而不是在其属性上调用,因此它不会“冻结”反对拼接(或更改道具的对象的属性值) )。我的问题是:

  1. 如何编写上述代码以尊重ReactJS哲学?
  2. 如果不修改道具是ReactJS哲学的核心原则,为什么不严格执行?

1 个答案:

答案 0 :(得分:1)

根据react哲学,建议您不要编辑道具,因为它不是react设计的方式(Thinking in React)。

您应该使用符合更改的视图的state,并且可以将一些数据从state传递到props

查看代码的正确示例:

var TodoList = React.createClass({
   propTypes: {
     todos: React.PropTypes.arrayOf(React.PropTypes.string).isRequired,
     onSomeAction: React.PropTypes.func.isRequired
   },


   render: function() {
     var todos = this.props.todos;
     var self  = this;
     return rce('div', {}
               ,rce('ul', {}
                  , (function(){
                    return todos.map(function(x, i) {
                      return rce('li', {key: i}, x);
                    });})())
         ,rce('button', {onClick: this.props.onSomeAction});
   }
 });

除非您在当前视图中管理自己的状态,否则点击按钮时应该做什么以及如何进行操作的逻辑应该放在视图的所有者中。

另外, 有一个概念定义了虚拟视图和智能视图。 简而言之,虚拟视图是这样的,它们只获取属性并在屏幕上显示一些数据,但它们不与其他对象交互或能够更改视图state。 但是,智能视图是这样的,它们与其他人交互,响应事件等,并能够改变他们的状态并将任何其他数据传递给其子女。

希望你现在更清楚......