从父 React 刷新子状态
Posted
技术标签:
【中文标题】从父 React 刷新子状态【英文标题】:Refreshing children state from parent React 【发布时间】:2015-07-03 03:29:00 【问题描述】:我有一个包含一些数据的表格,表格中的每个元素都是一个 React 类组件。它看起来像这样:
我想要的只是有一个用于“检查所有”功能的复选框(左上角复选框)。问题是我不知道如何解决这个问题,因为 props
和 state
。
我在单元素组件中有这样的代码:
getInitialState: function()
return component: this.props.data ;
,
render: function()
var data = this.state.component;
data = data.set('checked', this.props.data.get('checked'));
...
我知道我不应该从props
获得checked
参数,但这只是暂时的。
我遇到的问题是:当我更新父级中的checked
参数时,它不会更新状态,因为刷新后不会调用getInitialState
(是的,我知道它应该是这样的)。
我的问题是:我可以以某种方式更新子组件的状态吗? 或者这是实现这一目标的更好方法。
【问题讨论】:
【参考方案1】:带功能组件:
当父级更改提供的道具时,刷新子级内部状态的简单方法是通过useEffect()
:
在孩子们中:
const [data, setData] = useState(props.data);
useEffect( () =>
setData(props.data);
, [props.data]);
这样每次props.data
更改都会触发useEffect并强制为某些数据设置新状态,因此组件将“刷新”。
【讨论】:
是的,这就是我要找的。谢谢。【参考方案2】:我的做法是,你应该在父母的渲染中有这样的结构:
<ParentView>
this.props.rows.map(function(row)
<ChildRow props=row.props />
).bind(this)
</ParentView>
然后在row.props
上,您可以获得当前行项目是否被选中的信息。当父复选框被切换时,您将使用状态填充所有 row.props。
在孩子上,您将收到带有componentWillReceiveProps
的邮件,并且当复选框被切换时,您会施展魔法(例如设置正确的状态):
componentWillReceiveProps: function(props)
this.setState(isChecked: props.isChecked);
(来自 React 文档的信息:在此函数中调用 this.setState() 不会触发额外的渲染。)
子元素的渲染类似于:
<div>
<input type='checkbox' checked=this.state.isChecked />
<label>this.props.label</label>
</div>
【讨论】:
除非您非常小心,否则您最终可能会导致孩子与父母争夺对其状态的控制权。恕我直言,最好让孩子无国籍并仅由道具驱动。父级可以控制所有子级的选中状态。 @edoloughlin 谢谢你的评论,它救了我的命。【参考方案3】:您可以通过仅将所有子元素的选中状态存储在父元素中来解决此问题。孩子们只根据道具设置他们的检查状态(他们不为此使用状态)并调用父母提供的回调来改变这一点。
例如,在孩子身上:
render: function()
//... not showing other components...
<input type="checkbox"
value=this.props.value
checked=this.props.checked
onClick=this.props.onClick>
父级提供onClick
,它会更改子级在其状态下的已检查状态,并在子级重新渲染时将其传递回给子级。
在父级中:
getInitialState: function()
return
allChecked: false,
childrenChecked: new Array(NUM_CHILDREN) // initialise this somewhere (from props?)
,
render: function()
return <div>
<input type="checkbox" checked=this.state.allChecked>
children.map(function(child, i)
return <Child checked=this.state.childrenChecked[i]
onClick=function(index)
return function()
// update this.state.allChecked and this.state.childrenChecked[index]
.bind(this)
.bind(this)(i)
/>
).bind(this)
</div>;
-- 不检查错别字等。
【讨论】:
【参考方案4】:请参阅提升状态的react documentation。 在您的子组件中,您需要使用道具。要更新道具,您需要从父级提供更新功能。
【讨论】:
以上是关于从父 React 刷新子状态的主要内容,如果未能解决你的问题,请参考以下文章