所以我有一个很重要的组成部分:
<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}
所以,让我们说FirstComponent
是一个输入:
<input type="text" value={this.props.value}
onChange={(e)=>this.props.firstAction(e.target.value)}
</input>
好的,onChange
会触发道具firstAction
,这实际上是Flux操作,它将更新我的商店并使表单重新渲染。我在这里有两件好事,当用户提交表单时,我可以检查商店中FirstComponent的值,并且我还可以控制父组件中的所有状态。
但是,每次用户键入一个字符时,此onChange
回调都会调用一个操作(因此它可以产生大量调用,因此重新渲染)&lt; - 这会引发严重的性能问题吗?
相反,我可以使用引用,当用户按下提交按钮时,获取this.refs.myFirstComponent.state
...我也会得到值(那将是Uncontrolled Component?)但这听起来不是喜欢来自社区的推荐。
所以我的问题是,上面描述的第一种方法是一个很好的方法吗?我该如何优化它?那么只应该影响FirstComponent的重新渲染不会使SecondComponent等重新渲染? shouldComponentUpdate
是到这里的唯一途径吗?
修改1:
使用第一种方法我遇到了问题...我使用WebdriverIO进行了e2e测试,在文本字段中添加了一个值:http://webdriver.io/api/action/setValue.html
我不知道为什么,但如果我想添加“#34;测试&#34;进入输入,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测试工作。还有更多想法吗?
答案 0 :(得分:3)
您的第一种方法(即onChange
触发助焊剂操作,更新商店并使您的表单重新渲染)似乎是一个很好的方法。我一直在使用它,我也看到其他人也这样使用它。
关于您的以下评论:
但是,每次用户输入一个字符时,这个onChange回调都会调用一个动作(因此它可以产生大量的调用,因此重新渲染)&lt; - 这会引发严重的性能问题吗?
是的,我相信。我曾经创建了一个包含许多其他组件的组件以及一些输入字段。每当我在输入字段中输入一个字符时,整个组件(包含其他组件和输入字段)都会被重新渲染,从而导致性能问题。如果我快速键入,这是显而易见的。您可以使用https://facebook.github.io/react/docs/perf.html实际验证它。
无论如何,正如你所提到的,我如何解决这个问题是通过实施shouldComponentUpdate()
。
我想提到的一个小提示是创建一个自定义<Input />
组件,其中包含<input />
并实现shouldComponentUpdate()
(即this.props.value !== nextProps.value || this.props.checked !== nextProps.checked
)这样,如果你例如,创建一个表单组件,包含许多输入字段(使用自定义<Input />
),只有重新呈现的输入字段才会被重新呈现。
我也很想知道其他人如何解决这个问题。