React – 将表单元素状态传递给兄弟/父元素的正确方法?
- 假设我有一个React类P,它呈现了两个子类C1和C2。
- C1包含一个input字段。 我将这个input字段称为Foo。
- 我的目标是让C2对Foo中的变化做出反应。
我已经提出了两个解决scheme,但他们都不是很对。
第一个scheme
- 分配一个状态
state.input
。 - 在P中创build一个
onChange
函数,它接受一个事件并设置state.input
。 - 把这个转换成C1作为
props
,让C1绑定this.props.onChange
到Foo的onChange
。
这工作。 每当Foo的值发生变化时,就会触发P中的一个setState
,所以P将有input传递给C2。
但是,出于同样的原因,感觉不太对劲:我从一个子元素设置父元素的状态。 这似乎背叛了React的devise原则:单向数据stream。
这是我应该怎么做的,还是有更多的React-natural解决scheme?
解决scheme二
把Foo放在P.
但是,当我构build应用程序时,这是否应该遵循一个devise原则 – 将所有表单元素都放在最高级别的render
中?
就像在我的例子中,如果我有一个很大的C1渲染,我真的不想把整个render
的C1 render
为P,只是因为C1有一个表单元素。
我应该怎么做?
所以,如果我正确地理解你,你的第一个解决scheme是build议你保持你的根组件的状态? 我不能说React的创造者,但是通常我觉得这是一个合适的解决scheme。
保持状态是React创build的原因之一(至less我认为)。 如果你已经实现了自己的状态模式客户端来处理一个dynamic的用户界面,这个用户界面有很多相互依赖的移动块,那么你就会喜欢React,因为它减轻了很多状态pipe理的痛苦。
通过在层次结构中进一步保持状态,并通过事件更新,数据stream仍然是单向的,只是响应根组件中的事件,而不是通过双向绑定获取数据,你告诉Root组件“嘿,这里发生了一些事情,检查这些值”,或者你正在传递子组件中的一些数据的状态,以便更新状态。 你改变了C1中的状态,并且你希望C2知道它,所以通过更新Root组件中的状态并重新渲染,C2的道具现在是同步的,因为状态已经在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)
现在使用React构build应用程序,我想分享一些半年前我问过的问题。
我build议你阅读
- 反思中的思考
- 助焊剂
第一篇文章对理解如何构buildReact应用程序非常有帮助。
Flux回答了这个问题, 为什么你要这样构build你的React应用程序(而不是如何构build它)。 React只有系统的50%,通过Flux你可以看到整个系统,看看它们是如何构成一个连贯的系统。
回到问题。
至于我的第一个解决scheme,让处理程序反向运行是完全没问题的,因为数据仍然是单向的。
但是,是否让处理程序触发P中的setState可以是正确的,也可以是错误的,具体取决于您的情况。
如果应用程序是一个简单的Markdown转换器,C1是原始input,C2是HTML输出,可以让C1触发P中的setState,但有些人可能会认为这不是推荐的方法。
但是,如果应用程序是待办事项列表,C1是创build新待办事项的input,C2是HTML中的待办事项列表,您可能需要处理比P更高的两级 – dispatcher
,让store
更新data store
,然后将数据发送到P并填充视图。 看到Flux文章。 这里是一个例子: Flux – TodoMVC
一般来说,我更喜欢待办事项列表示例中描述的方式。 您在应用中的状态越差越好。
您应该学习Redux和ReactRedux库。它将在一个商店中构build您的状态和道具,稍后您可以在组件中访问它们。