将表单元素状态传递给兄弟/父元素的正确方法是什么? [英] What's the right way to pass form element state to sibling/parent elements?

查看:31
本文介绍了将表单元素状态传递给兄弟/父元素的正确方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  • 假设我有一个 React 类 P,它呈现两个子类,C1 和 C2.
  • C1 包含一个输入字段.我将此输入字段称为 Foo.
  • 我的目标是让 C2 对 Foo 中的变化做出反应.

我想出了两个解决方案,但都感觉不太对.

第一个解决方案:

  1. 为 P 分配一个状态,state.input.
  2. 在 P 中创建一个 onChange 函数,它接收一个事件并设置 state.input.
  3. 将此onChange作为props传递给C1,让C1将this.props.onChange绑定到onChange代码> Foo.

这有效.每当 Foo 的值发生变化时,就会触发 P 中的 setState,因此 P 将有输入传递给 C2.

但出于同样的原因,感觉不太正确:我正在从子元素设置父元素的状态.这似乎违背了 React 的设计原则:单向数据流.
这是我应该做的,还是有更自然的 React 解决方案?

第二种解决方案:

只需将 Foo 放在 P 中即可.

但这是否是我构建应用程序时应该遵循的设计原则——将所有表单元素放在最高级别类的render中?

就像在我的例子中,如果我有大量的 C1 渲染,我真的不想仅仅因为将 C1 的整个 render 放到 P 的 renderC1 有一个表单元素.

我该怎么做?

解决方案

那么,如果我理解正确的话,您的第一个解决方案是建议您在根组件中保持状态?我不能代表 React 的创建者,但总的来说,我发现这是一个合适的解决方案.

维护状态是创建 React 的原因之一(至少我认为).如果您曾经实现过自己的状态模式客户端来处理具有许多相互依赖的移动部分的动态 UI,那么您会喜欢 React,因为它减轻了很多这种状态管理的痛苦.

通过在层次结构中进一步保持状态,并通过事件更新它,您的数据流仍然几乎是单向的,您只是响应根组件中的事件,您并没有真正通过两个方式绑定,您是在告诉 Root 组件嘿,这里发生了一些事情,请检查值",或者您正在向上传递子组件中某些数据的状态以更新状态.您更改了 C1 中的状态,并且希望 C2 知道它,因此,通过更新 Root 组件中的状态并重新渲染,C2 的 props 现在处于同步状态,因为状态已在 Root 组件中更新并传递.

class Example extends React.Component {构造函数(道具){超级(道具)this.state = { 数据:'测试' }}使成为 () {返回 (<div><C1 onUpdate={this.onUpdate.bind(this)}/><C2 data={this.state.data}/>

)}onUpdate (data) { this.setState({ data }) }}类 C1 扩展了 React.Component {使成为 () {返回 (<div><input type='text' ref='myInput'/><input type='button' onClick={this.update.bind(this)} value='Update C2'/>

)}更新 () {this.props.onUpdate(this.refs.myInput.getDOMNode().value)}})类 C2 扩展了 React.Component {使成为 () {返回 <div>{this.props.data}</div>}})ReactDOM.renderComponent(, document.body)

  • Suppose I have a React class P, which renders two child classes, C1 and C2.
  • C1 contains an input field. I'll refer to this input field as Foo.
  • My goal is to let C2 react to changes in Foo.

I've come up with two solutions, but neither of them feels quite right.

First solution:

  1. Assign P a state, state.input.
  2. Create an onChange function in P, which takes in an event and sets state.input.
  3. Pass this onChange to C1 as a props, and let C1 bind this.props.onChange to the onChange of Foo.

This works. Whenever the value of Foo changes, it triggers a setState in P, so P will have the input to pass to C2.

But it doesn't feel quite right for the same reason: I'm setting the state of a parent element from a child element. This seems to betray the design principle of React: single-direction data flow.
Is this how I'm supposed to do it, or is there a more React-natural solution?

Second solution:

Just put Foo in P.

But is this a design principle I should follow when I structure my app—putting all form elements in the render of the highest-level class?

Like in my example, if I have a large rendering of C1, I really don't want to put the whole render of C1 to render of P just because C1 has a form element.

How should I do it?

解决方案

So, if I'm understanding you correctly, your first solution is suggesting that you're keeping state in your root component? I can't speak for the creators of React, but generally, I find this to be a proper solution.

Maintaining state is one of the reasons (at least I think) that React was created. If you've ever implemented your own state pattern client side for dealing with a dynamic UI that has a lot of interdependent moving pieces, then you'll love React, because it alleviates a lot of this state management pain.

By keeping state further up in the hierarchy, and updating it through eventing, your data flow is still pretty much unidirectional, you're just responding to events in the Root component, you're not really getting the data there via two way binding, you're telling the Root component that "hey, something happened down here, check out the values" or you're passing the state of some data in the child component up in order to update the state. You changed the state in C1, and you want C2 to be aware of it, so, by updating the state in the Root component and re-rendering, C2's props are now in sync since the state was updated in the Root component and passed along.

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)

这篇关于将表单元素状态传递给兄弟/父元素的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆