【问题标题】:React Form controlled by a Flux Store (Best practice?)由 Flux Store 控制的 React Form(最佳实践?)
【发布时间】:2015-10-22 12:35:19
【问题描述】:

所以我有一个很大的组件就是我的表单:

<form>
 <FirstComponent value={this.state.firstValue}/>
 <SecondComponent value={this.state.secondValue}/>
 {more components here}
 <input type="submit" ... />
</form>

此表单组件正在侦听使用 firstActionsecondAction 等更新其值的商店。

注意:组件根据返回 {firstValue: something, secondValue: something, etc} 的 store.getState() 更新其状态

假设我的FirstComponent是一个输入:

<input type="text" value={this.props.value} 
   onChange={(e)=>this.props.firstAction(e.target.value)}
</input>

好的,所以onChange 触发了 firstAction 属性,这实际上是 Flux 操作,它将更新我的商店并使表单重新呈现。我这里有两个好处,当用户提交表单时,我可以在我的商店中检查 FirstComponent 的值,并且我还可以从父组件控制我的所有状态。

但是,这个onChange 回调会在用户每次输入一个字符时调用一个动作(因此它会产生大量调用,因此会重新渲染)

相反,我可以使用 refs,当用户按下提交按钮时,得到 this.refs.myFirstComponent.state... 我也将拥有该值(那将是 Uncontrolled Component?)但这听起来不像是来自社区。

所以我的问题是,我上面描述的第一种方法是一个好方法吗?我该如何优化它?那么应该只影响 FirstComponent 的重新渲染不会使 SecondComponent 等重新渲染? shouldComponentUpdate是唯一的途径吗?


编辑 1:

第一种方法我面临一个问题...我有一个使用 WebdriverIO 的 e2e 测试,在文本字段中添加一个值:http://webdriver.io/api/action/setValue.html

我不知道为什么,但是如果我尝试在输入中添加单词“Testing”,webdriver 只会添加最后一个字母。如果根本不使用状态/存储,这个问题就消失了。但是,如果我的 FirstComponent 内部有状态,则类似于:

<input type="text" value={this.state.value} 
   onChange={(e)=>this.setState({firstValue: e.target.value})}
   onBlur={()=>this.props.callback(this.state.firstValue)}
</input>

在这种情况下,组件在键入时似乎反应更快(仅呈现自身),然后,当用户移除焦点时,它会更新商店。我不得不说,我不喜欢这种方法,因为它不遵循提升状态的模式(而且我觉得我在复制状态)但它似乎工作得更快更重要:我的 e2e 测试有效。还有什么想法吗?

【问题讨论】:

    标签: javascript forms reactjs reactjs-flux


    【解决方案1】:

    您的第一种方法(即onChange 触发flux 操作,更新商店并使您的表单重新呈现)似乎是一个不错的方法。我一直这样使用它,我也看到其他人也这样使用它。

    关于您的以下评论:

    然而,这个 onChange 回调会在用户每次输入一个字符时调用一个动作(所以它会产生很多调用,因此会重新渲染)

    是的,我相信是的。我曾经创建了一个组件,其中包含许多其他组件以及一些输入字段。每当我在输入字段中键入一个字符时,整个组件(连同它包含的其他组件和输入字段)都会重新渲染,从而导致性能问题。如果我打字快,那就很明显了。您实际上可以使用https://facebook.github.io/react/docs/perf.html 进行验证。

    无论如何,正如你所提到的,我是通过实现shouldComponentUpdate() 来解决这个问题的。

    我想提一下的一个小技巧是创建一个自定义的&lt;Input /&gt; 组件,该组件环绕&lt;input /&gt; 并实现shouldComponentUpdate()(即this.props.value !== nextProps.value || this.props.checked !== nextProps.checked)这样,如果您创建一个表单组件,例如,有许多输入字段(使用自定义 &lt;Input /&gt;),只有更改的输入字段会重新呈现。

    不过,我也很想看看其他人如何解决这个问题。

    【讨论】:

    • 检查我的编辑 1,使用我在 e2e 测试中遇到问题的操作方法...
    • 为什么会导致性能问题?我认为 React 的虚拟 DOM 会在内部处理此类检查,并且只呈现已更改的内容。在性能方面,这是 React 的显着特征。我错了吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-21
    • 2016-05-02
    • 2019-02-19
    • 2018-09-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多