这可能是在回答问题和自以为是之间的那条线,但我会来回顾如何构建ReactJS组件,因为复杂性增加并且可以使用某些方向 .
Coming from AngularJS, I want to pass my model into the component as a property and have the component modify the model directly. Or should I be splitting the model up into various state properties and compiling it back together when sending back upstream? What is the ReactJS way?
以博客文章编辑器为例 . 试图直接修改模型最终看起来像:
var PostEditor = React.createClass({
updateText: function(e) {
var text = e.target.value;
this.props.post.text = text;
this.forceUpdate();
},
render: function() {
return (
<input value={this.props.post.text} onChange={this.updateText}/>
<button onClick={this.props.post.save}/>Save</button>
);
}
});
这似乎不对 .
是否更多React方法来创建我们的 text
模型属性 state
,并在保存之前将其编译回模型:
var PostEditor = React.createClass({
getInitialState: function() {
return {
text: ""
};
},
componentWillMount: function() {
this.setState({
text: this.props.post.text
});
},
updateText: function(e) {
this.setState({
text: e.target.value
});
},
savePost: function() {
this.props.post.text = this.state.text;
this.props.post.save();
},
render: function() {
return (
<input value={this.state.text} onChange={this.updateText}/>
<button onClick={this.savePost}/>Save</button>
);
}
});
这不需要调用 this.forceUpdate()
,但随着模型的增长,(帖子可能有作者,主题,标签,评论,评级等......)组件开始变得非常复杂 .
第一种方法是ReactLink的方法吗?
6 回答
Updating 2016: React已更改,解释"props vs state"变得非常简单 . 如果组件需要更改数据 - 将其置于某个状态,否则将置于道具中 . 因为 props are read-only 现在 .
道具和国家之间的确切区别是什么?
你可以找到很好的解释here(完整版)
阅读Thinking in React:
我不确定我是否回答了你的问题,但我发现,特别是在大型/不断发展的应用程序中,容器/组件模式运行得非常好 .
基本上你有两个React组件:
a "pure"显示组件,用于处理样式和DOM交互;
一个容器组件,用于处理访问/保存外部数据,管理状态和呈现显示组件 .
示例
N.B. 这个例子可能过于简单,无法说明这种模式的好处,因为对于这种简单的案例来说这是非常冗长的 .
好处
通过将显示逻辑和数据/状态管理分开,您有一个可重复使用的显示组件:
可以使用react-component-playground之类的东西轻松地使用不同的道具集进行迭代
可以用不同的容器包装以实现不同的行为(或者与其他组件结合使用以构建应用程序的更大部分
您还有一个容器组件,用于处理所有外部通信 . 如果您稍后进行任何重大更改,这将使您更容易灵活地访问数据 .
这种模式也使得编写和实现单元测试变得更加直接 .
迭代了一个大的React应用程序几次后,我发现这种模式让事情变得相对轻松,特别是当你有更大的组件与计算样式或复杂的DOM交互时 .
*阅读通量模式,看看Marty.js,这很大程度上激发了这个答案(我最近一直在使用很多)Redux(和react-redux),它们非常好地实现了这种模式 .
我认为你正在使用Facebook已经解释过的反模式link
这是你找到的东西:
第一次渲染内部组件时,它将{foo:'bar'}作为值prop . 如果用户单击锚点,则父组件的状态将更新为{value:{foo:'barbar'}},从而触发内部组件的重新呈现过程,该过程将接收{foo:'barbar'} as道具的新 Value .
问题是,由于父组件和内组件共享对同一对象的引用,当对象在onClick函数的第2行变异时,内部组件所具有的prop将会改变 . 因此,当重新呈现过程开始并调用shouldComponentUpdate时,this.props.value.foo将等于nextProps.value.foo,因为实际上this.props.value引用与nextProps.value相同的对象 .
因此,由于我们会错过道具上的更改并使重新渲染过程短路,因此UI不会从“bar”更新为“barbar”
你的第二种方法更像是它 . React并不关心模型,因为它关心的是 Value 以及它们如何在您的应用程序中流动 . 理想情况下,您的帖子模型将存储在根目录中的单个组件中 . 然后创建子组件,每个组件都使用模型的一部分 .
您可以将回调传递给需要修改数据的子项,并从子组件中调用它们 .
修改this.props或this.state直接不是一个好主意,因为React将无法接受更改 . 这是因为React对你的后道具进行浅层比较,以确定它是否已经改变 .
我制作了这个jsfiddle来展示数据如何从外部组件流向内部组件:
http://jsfiddle.net/jxg/M3CLB/
handleClick
方法显示了3种(im)正确更新状态的方法:来自React doc
从 TrySpace :当更新道具(或状态)时(通过setProps / setState或parent),组件也会重新渲染 .