当前位置: 代码迷 >> JavaScript >> 由Flux Store控制的React Form(最佳实践?)
  详细解决方案

由Flux Store控制的React Form(最佳实践?)

热度:95   发布时间:2023-06-05 11:41:26.0

所以我有一个很重要的组成部分:

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

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

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

那么让我们说我的FirstComponent是一个输入:

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

好的,所以onChange触发了prop的firstAction ,它实际上是Flux动作,它将更新我的商店并使表单重新渲染。 我有两个好东西,当用户提交表单时,我可以检查我的商店中的FirstComponent的值,并且我还控制来自父组件的所有状态。

但是,每次用户键入一个字符时,此onChange回调将调用一个操作(因此它可以产生大量调用,因此重新渲染)< - 这会引发严重的性能问题吗?

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

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


编辑1:

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

我不知道为什么,但如果我试图在输入中添加“测试”这个词,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测试工作。 还有什么想法吗?

你的第一种方法(即onChange fires flux动作更新商店并使你的表格重新渲染)似乎是一个很好的方法。 我一直在使用它,我也见过其他人也这样使用它。

关于您的以下评论:

但是,每次用户键入一个字符时,此onChange回调将调用一个操作(因此它可以产生大量调用,因此重新渲染)< - 这会引发严重的性能问题吗?

是的,我相信。 我曾经创建了一个包含许多其他组件的组件以及一些输入字段。 每当我在输入字段中输入一个字符时,整个组件(包含其他组件和输入字段)都会被重新渲染,从而导致性能问题。 如果我快速键入,这是显而易见的。 您可以使用实际验证它。

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

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

不过,我也很想知道其他人是如何处理这个问题的。

  相关解决方案