问题描述
所以我有一个很重要的组成部分:
<form>
 <FirstComponent value={this.state.firstValue}/>
 <SecondComponent value={this.state.secondValue}/>
 {more components here}
 <input type="submit" ... />
</form>
 
   
     此表单组件正在侦听使用firstAction , secondAction等更新其值的存储。 
 
     注意:组件基于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测试工作。 还有什么想法吗?
1楼 
  
    Brian Park 
    3 
    2015-07-31 03:30:16
  
 
  
     你的第一种方法(即onChange fires flux动作更新商店并使你的表格重新渲染)似乎是一个很好的方法。 
     我一直在使用它,我也见过其他人也这样使用它。 
关于您的以下评论:
但是,每次用户键入一个字符时,此onChange回调将调用一个操作(因此它可以产生大量调用,因此重新渲染)< - 这会引发严重的性能问题吗?
是的,我相信。 我曾经创建了一个包含许多其他组件的组件以及一些输入字段。 每当我在输入字段中输入一个字符时,整个组件(包含其他组件和输入字段)都会被重新渲染,从而导致性能问题。 如果我快速键入,这是显而易见的。 您可以使用实际验证它。
 
     无论如何,正如你所提到的,我如何解决这个问题是通过实现shouldComponentUpdate() 。 
 
     我想提一个小技巧是创建一个自定义<Input />组件,它包含<input />并实现shouldComponentUpdate() (即this.props.value !== nextProps.value || this.props.checked !== nextProps.checked )这样,如果您创建一个表单组件,例如,使用许多输入字段(使用自定义<Input /> ),则只会重新呈现更改的输入字段。 
不过,我也很想知道其他人是如何处理这个问题的。