我提出了两种解决方案,但都感觉不太对劲。
第一个解决方案:
state.input
onChange
props
this.props.onChange
这行得通。每当 Foo 的值发生变化时,它都会触发setStateP 中的 a,因此 P 将有输入传递给 C2。
setState
但出于同样的原因,感觉不太对劲:我正在从子元素设置父元素的状态。这似乎背叛了 React 的设计原则:单向数据流。 这是我应该这样做的方式,还是有更自然的解决方案?
第二种解决方案:
只需将 Foo 放在 P 中即可。
但这是我在构建应用程序时应该遵循的设计原则——将所有表单元素放在render最高级别的类中吗?
render
就像在我的示例中一样,如果我有 C1 的大型渲染,我真的不想仅仅因为 C1 有一个表单元素而将整个renderC1 放到renderP 中。
我该怎么做?
所以,如果我对您的理解正确,您的第一个解决方案是建议您在根组件中保持状态?我不能代表 React 的创建者,但总的来说,我发现这是一个合适的解决方案。
维护状态是创建 React 的原因之一(至少我认为)。如果您曾经实现过自己的状态模式客户端来处理具有大量相互依赖的移动部分的动态 UI,那么您会喜欢 React,因为它减轻了很多这种状态管理的痛苦。
通过在层次结构中进一步保持状态,并通过事件更新它,您的数据流仍然几乎是单向的,您只是响应 Root 组件中的事件,您并没有真正通过双向绑定获取数据,您是在告诉 Root 组件“嘿,这里发生了一些事情,请检查值”,或者您正在向上传递子组件中某些数据的状态以更新状态。您更改了 C1 中的状态,并且希望 C2 知道它,因此,通过更新 Root 组件中的状态并重新渲染,C2 的 props 现在是同步的,因为状态在 Root 组件中已更新并传递.
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)