问题描述
这可能是在回答和固执己见之间徘徊,但随着复杂性的增加,我会反复讨论如何构建 ReactJS 组件,并且可以使用一些方向.
This may be treading that line between answerable and opinionated, but I'm going back and forth as to how to structure a ReactJS component as complexity grows and could use some direction.
来自 AngularJS,我想将我的模型作为属性传递给组件,并让组件直接修改模型.或者我应该将模型拆分为各种 state
属性并在向上游发送时将其编译回一起?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?
以博客文章编辑器为例.尝试直接修改模型最终看起来像:
Take the example of a blog post editor. Trying to modify the model directly ends up looking like:
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
,并在保存之前将其编译回模型:
Is it more the React way to make our text
model property state
, and compile it back into the model before saving like:
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()
,但是随着模型的增长,(帖子可能有作者、主题、标签、评论、评级等......) 组件开始变得非常复杂.
This doesn't require a call to this.forceUpdate()
, but as the model grows, (a post may have an author, subject, tags, comments, ratings, etc...) the component starts getting really complicated.
ReactLink 的第一种方法是否可行?>
Is the first method with ReactLink the way to go?
推荐答案
你的第二种方法更像它.React 并不关心模型,而是关心 值 以及它们如何在您的应用程序中流动.理想情况下,您的后期模型将存储在根的单个组件中.然后创建子组件,每个组件都使用模型的一部分.
Your second approach is more like it. React doesn't care about models so much as it cares about values and how they flow through your app. Ideally, your post model would be stored in a single component at the root. You then create child components that each consume parts of the model.
您可以将回调传递给需要修改数据的子组件,并从子组件调用它们.
You can pass callbacks down to the children that need to modify your data, and call them from the child component.
直接修改 this.props 或 this.state 不是一个好主意,因为 React 将无法接受更改.那是因为 React 对你的 post prop 做了一个浅层比较,以确定它是否发生了变化.
Modifying this.props or this.state directly is not a good idea, because React will not be able to pick up on the changes. That's because React does a shallow comparison of your post prop to determine if it has changed.
我制作了这个 jsfiddle 来展示数据如何从外部组件流向内部组件.
I made this jsfiddle to show how data could flow from an outer to an inner component.
handleClick
方法展示了 3 种(im)正确更新状态的方法:
The handleClick
method shows 3 ways to (im)properly update state:
var Outer = React.createClass({
getInitialState: function() {
return {data: {value: 'at first, it works'}};
},
handleClick: function () {
// 1. This doesn't work, render is not triggered.
// Never set state directly because the updated values
// can still be read, which can lead to unexpected behavior.
this.state.data.value = 'but React will never know!';
// 2. This works, because we use setState
var newData = {value: 'it works 2'};
this.setState({data: newData});
// 3. Alternatively you can use React's immutability helpers
// to update more complex models.
// Read more: http://facebook.github.io/react/docs/update.html
var newState = React.addons.update(this.state, {
data: {value: {$set: 'it works'}}
});
this.setState(newState);
},
render: function() {
return <Inner data={this.state.data} handleClick={this.handleClick} />;
}
});
这篇关于ReactJS 状态与道具的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!