将初始状态作为React道具传递给一个组件是一种反模式

149 阅读1分钟

将初始状态作为一个道具传递给一个组件是一种反模式,因为getInitialState 方法只在组件第一次渲染时被调用,之后就不再调用。这意味着,如果你重新渲染父类,同时传递一个不同的值作为道具,该组件将不会更新用户界面,因为它将保持第一次渲染时的状态。这将使应用程序非常容易出错。

解决方案?让组件成为无状态。它们更容易测试,因为它们是基于输入来渲染输出的。让父组件包含传入的数据作为它自己的状态,然后如果状态改变,它就重新渲染它的子组件,同时通过props ,传入它们需要的一切。

这在React中是什么样子的?

父组件(或所谓的 "控制器视图")将通过ajax调用获得所有的数据(使用flux模式),并将其放入getInitialState

另一个解决方案是向子组件发送 "处理程序",然后这些父组件的处理程序一旦被子组件调用,就会进行setState操作,从而对UI进行重新渲染。StackOverflow上有一个很好的例子:reactjs-two-components-communicating

最好的解决方案是有一个 "容器 "或 "ControllerView "将处理程序传递给子组件...

var ListContainer = React.createClass({
	handleFilterUpdate(filterValue){
		this.setState({
			nameFilter: filterValue
		});
	}	,
	render(){
		return (
			<div>
				<Filters updateFilter={this.handleFilterUpdate}/>
				<List items={displayedItems}/>
			</div>
		);
	}
});

var Filters = React.createClass({
	handleFilterChange(){
		var value = this.refs.filterInput.getDOMNode().value;
		this.props.updateFilter(value);
	},
	render(){
		return (
			<div><input ... ref="filterInput" onChange={this.handleFilterChange} /></div>
		)
	}
});
// this is not good
getInitialState: function(){
	return {
		text: this.props.text
	}
}

这样做的另一个问题是,传递text 属性的父代可能期望它包含最新的值,但它没有。

getInitialState ,使用从父类传递下来的道具来生成状态,往往会导致 "真实来源 "的重复,而真实数据就在那里。