【发布时间】:2015-10-22 12:35:19
【问题描述】:
所以我有一个很大的组件就是我的表单:
<form>
<FirstComponent value={this.state.firstValue}/>
<SecondComponent value={this.state.secondValue}/>
{more components here}
<input type="submit" ... />
</form>
此表单组件正在侦听使用 firstAction、secondAction 等更新其值的商店。
注意:组件根据返回 {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