我是React的新手,每次onChange操作发生时,我都会尝试更新子组件中父组件的状态。 onchange操作来自一个输入框,当输入字母时,它会使用已键入的值更新searchInputVal的状态。我有一个父<App/>
组件,其中包含以下属性和状态:
updateSampleFilteredState(filteredSamples) {
this.setState({
samples: filteredSamples
});
},
getInitialState () {
return {
samples:allSamples,
searchInputVal:""
}}
我将属性和状态传递给子组件:
updateNewSampleState(filteredSamples){
return (
this.props.updateSampleFilteredState(filteredSamples)
)
}
render() {
const filteredSamples = this.props.samples.filter(sample => {
return sample.sampleFamily.toLowerCase().indexOf(this.props.searchInputVal.toLowerCase()) !== -1;
});
this.updateNewSampleState(filteredSamples);
return <div className="samples-container-inner-styling">
{
filteredSamples.map((sample) => {
return (...
在我添加行this.updateNewSampleState(filteredSamples);
之前,子组件会渲染过滤得很好,但显然不会使用新的过滤状态更新样本状态。当我在行this.updateNewSampleState(filteredSamples);
中执行组件中的函数来设置新状态时,我得到一个重新发生的错误列表,最终导致我的应用程序崩溃。这些错误说明反模式。我不确定如何更新状态?
答案 0 :(得分:2)
您不应该从渲染功能更新状态,而您正面临着这样做的原因。每次调用setState时,组件都会重新渲染,所以如果你在render函数中调用它,它将再次被调用,等等......你应该问问自己为什么要在那里调用那个函数。我猜你可以在你用于输入的onChange函数中做到这一点。
答案 1 :(得分:0)
正如@César已经提到的,在渲染器中设置状态没有意义,因为设置状态会触发组件的重新渲染,所以你基本上会得到类似无限渲染循环的东西。
鉴于您仅从道具计算filteredSamples
,您可以在constructor
中计算该状态:
构造函数是初始化状态的正确位置。
但是,在构造函数中从props派生状态时请注意以下事项:
如果您知道自己在做什么,可以根据道具初始化状态。 [...]
要小心这种模式,因为它有效地“分叉”道具并可能导致错误。您不必将道具同步到州,而是经常想要lift the state up。
如果你通过将它们用于状态来“分叉”道具,你可能还需要实现
componentWillReceiveProps(nextProps)
以使状态与它们保持同步。但是提升状态通常更容易,而且容易出错。