我已经提出了两种解决方案,但是它们都不对。
第一个解决方案:
state.input
onChange
props
this.props.onChange
这可行。每当Foo的值改变时,它都会触发setStateP中的a,因此P会将输入传递给C2。
setState
但是由于相同的原因,感觉不太正确:我正在从子元素中设置父元素的状态。这似乎背叛了React的设计原理:单向数据流。 这是我应该怎么做,还是有一个更自然的React解决方案?
第二种解决方案:
只需将Foo放在P中即可。
但这是我在构建应用程序时应遵循的设计原则—将所有表单元素都放在render最高级别的类中?
render
就像在我的示例中一样,如果我渲染了很大的C1,我真的不想仅仅将renderC1 放在renderP中就因为C1具有表单元素。
我该怎么办?
因此,如果我对您的理解正确,那么您的第一个解决方案是建议您将状态保留在根组件中?我不能代表React的创建者,但是总的来说,我发现这是一个合适的解决方案。
保持状态是创建React的原因之一(至少在我看来)。如果您曾经实现自己的状态模式客户端来处理具有很多相互依赖的动态部件的动态UI,那么您会喜欢React的,因为它减轻了很多这种状态管理的麻烦。
通过在层次结构中进一步保持状态,并通过事件对其进行更新,您的数据流仍然几乎是单向的,您只是在响应Root组件中的事件,实际上并没有通过两种方式绑定那里的数据,您要告诉Root组件“嘿,这里发生了什么事,请检查值”,或者您要向上传递子组件中某些数据的状态以更新状态。您在C1中更改了状态,并且希望C2知道它,因此,通过更新Root组件中的状态并重新渲染,由于C2的道具在Root组件中进行了更新并传递了,因此C2的道具现在处于同步状态。
class Example extends React.Component { constructor (props) { super(props) this.state = { data: 'test' } } render () { return ( <div> <C1 onUpdate={this.onUpdate.bind(this)}/> <C2 data={this.state.data}/> </div> ) } onUpdate (data) { this.setState({ data }) } } class C1 extends React.Component { render () { return ( <div> <input type='text' ref='myInput'/> <input type='button' onClick={this.update.bind(this)} value='Update C2'/> </div> ) } update () { this.props.onUpdate(this.refs.myInput.getDOMNode().value) } }) class C2 extends React.Component { render () { return <div>{this.props.data}</div> } }) ReactDOM.renderComponent(<Example/>, document.body)