为什么我不能更新react.js中的道具?

为什么我们有stateprops ? 为什么我们不只有一个数据源? 我想更新一个组件的props ,并重新渲染自己和所有的孩子。 看起来很简单,但我不知道如何让组件更新自己或其父母的道具。

感谢您的帮助。

React哲学是道具应该是不变的,自上而下的。 这意味着父母可以向孩子发送喜欢的任何道具值,但孩子不能修改自己的道具。 你所做的是对进来的道具作出反应,然后如果你想要,根据进来的道具修改你的孩子的状态。

所以你永远不要更新自己的道具或者父母的道具。 永远。 你只能更新你自己的状态,并对父母给予的道具值作出反应。

如果你想在一个孩子身上发生一个动作来修改这个状态,那么你所做的就是把callback传递给它可以在给定动作上执行的孩子。 这个callback可以修改父母的状态,然后可以在重新呈现时发送不同的道具给孩子。

在React中, stateprops服务于不同的目标: state允许一个组件保持一些变化的价值,而props则是把这些价值传播给儿童的机制。

孩子们不允许自己改变通过道具获得的价值,因为Reactdevise师发现以这种方式维护应用程序更容易。 他们的观点是,当只有一个组件被允许更新某个状态时,更容易发现谁修改了它,并find了错误的根源。

组件本身改变它的状态 ,而不是改变它自己,而是改变孩子们的道具

 <Parent> <Child name={ this.state.childName } /> </Parent> 

家长可以改变自己的状态,改变孩子的名字,但会改变孩子的道具。

编辑1:为了从孩子向其父母调用事件,你应该像这样传递一个事件处理程序:

 var Child = React.createClass({ render: function() { return (<button onClick={ this.props.onClick }>Hey</button>); } }); var Parent = React.createClass({ onChildClick: console.log.bind(console), // will print the event.. render: function() { return (<Child onClick={ this.onChildClick } />); } }); React.renderComponent(<Parent />, document.body); 

在这个代码中,当你点击Child的button时,它会将事件传递给它的父对象。 传递事件的目的是解耦组件。 也许在你的应用程序中你需要这个特定的动作,但是在另一个应用程序中,你会以不同的方式使用它。

回答为什么

在React里,道具从父母之间stream下来。

这意味着当我们调用ReactDOM.render ,React可以渲染根节点,传递任何道具,然后忘记那个节点。 完成了。 它已经被渲染了。

这发生在每个组件上,我们渲染它,然后在树上向下移动,深度优先。

如果一个组件可以改变它的道具,我们将改变父节点已经渲染后父节点可访问的对象。 这可能会导致各种奇怪的行为,例如, user.name可能在应用程序的一部分中有一个值,而在不同部分中可能有不同的值,并且可能在下次触发渲染时更新自身。

举一个虚构的例子:

 // App renders a user.name and a profile const App = (props) => React.createElement('div', null, [ props.user.name, React.createElement(Profile, props} ]) // Profile changes the user.name and renders it // Now App has the wrong DOM. const Profile = ({user}) => { user.name = "Voldemort" // Uh oh! return React.createElement('div', null, user.name); } // Render the App and give it props ReactDOM.render( React.createElement(App, {user: {name: "Hermione"}}), document.getElementById('app')) ); 

我们呈现应用。 它输出“Hermione”到Shadow DOM。 我们渲染Profile,输出“Voldemort”。 该应用程序现在是错的。 应该说“Voldemort”,因为user.name是“Voldemort”,但是我们已经输出了“Hermione”,改变它为时已晚。

该值在应用程序的不同部分会有所不同。

修改道具将是双向绑定

变异的道具将是双向绑定的一种forms。 我们将修改树上更高的另一个组件可能依赖的值。

angular1有这个,你可以随时更改任何数据,无论你在哪里。 为了工作,它需要一个周期性的消化。 基本上,它会四处循环,重新渲染DOM,直到所有数据完成传播。 这是Angular 1如此缓慢的原因之一。

你可以自己传递父对象,我的意思是这个

 <Parent> <Child name={this} /> </Parent> 

并在子组件中使用{this.props.name.state.childname}这适用于我

与这里提供的答案相反,如果你不介意嘲弄有关“反应方式”的迂回曲折,你实际上可以直接更新道具。 在React.js中,find以下几行代码:

 Object.freeze(element.props); Object.freeze(element); 

并发表评论。 瞧,可变的道具!