挂载后,ReactJS组件可以接收新属性或新状态.通常可以使用不同的方法来解决相同的问题.
有效负载用于设置新状态:
getInitialState: function() {
return {data: {}};
},
componentDidMount: function() {
requestData().then(function(payload) {
this.setState({data: payload});
});
}
// this.state.data is available for use
或将新的有效负载作为道具传递:
requestData().then(function(payload) {
React.render(<Example data={payload}/>, container);
});
// this.props.data is available for use
在两种情况下,在解析requestData时都会更新组件.组件内部发生了什么变化?
解决方法:
国家和道具之间的最大区别是责任.对于状态,组件自己来获取所需的任何数据,并更新其自己的状态,这将导致组件重新呈现.
对于props,获取数据的不是组件本身,而是父组件.父级获取数据并更新其状态,然后在render方法中将该状态作为道具传递给子级组件.
本身没有任何状态但仅通过props传递数据的组件更容易理解.它们是“纯净的”,因为它们没有副作用.将相同的道具传递给该组件将始终提供相同的输出.这些组件通常仅具有render方法,因为它们通常不需要其他任何东西,而只是渲染作为道具传递的东西.
当您的组件具有状态时,您需要更多地考虑如何使状态发生变化以及它所引起的副作用.
因此,由于无状态组件更容易保持无缺陷,因此使用React时的经验法则是尽可能少地使用有状态组件,并将其保持在组件层次结构的顶部.然后,这些有状态组件将数据作为道具传递给无状态组件.如果您有几个有状态的组件,而其余的则是无状态的,则您知道应用程序的大多数复杂性都包含在这些有状态的应用程序中.因此,专注于保持正确性会更容易,而不是到处都散布着复杂性.
编辑
关于术语“组件层次结构”的更新.
组件层次结构是您的React组件,最顶层的组件是您传递给React.render()的组件.因此,这是一个示例,其中“顶部”是顶部,“底部”是底部.您想将状态保持在“顶部”而不是“底部”.
var Top = React.createClass({
getInitialState() {
return {
data: {title: '', contents: ''}
};
},
componentWillMount() {
SomeAsyncService.fetch()
.then(data => this.setState({data: data}));
},
render() {
return (
<Middle
title={this.state.data.title}
contents={this.state.data.contents}
/>
);
}
});
var Middle = React.createClass({
render() {
return (
<h1>{this.props.data.title}</h1>
<Bottom contents={this.props.contents} />
);
}
});
var Bottom = React.createClass({
render() {
return (
<p>{this.props.contents}</p>
);
}
});
理想情况下,您获取并管理该*组件中所有应用程序的状态,然后仅将数据作为道具传递给子组件,而它们对它们的来源一无所知,从而使它们本质上更加简单.但是,就像我说的那样,仅拥有一个有状态的组件可能会失控,但是您应该努力使状态尽可能接近顶层.
或者,如果您使用的是react-router,则在每个路由处理程序组件中获取数据,并将数据向下传递到该路由子组件.