我在更新树形结构中的嵌套组件时遇到了一些麻烦。我创建了以下最小示例来说明问题:Codesandbox.io
为了完整起见,这是要嵌套的组件:
class Node extends React.Component {
constructor(props) {
super(props);
this.state = {
selected: props.selected
};
this.toggleSelected = this.toggleSelected.bind(this);
}
toggleSelected() {
this.setState({
selected: !this.state.selected
});
}
render() {
return (
<>
<div onClick={this.toggleSelected}>
Selected: {this.state.selected ? "T" : "F"}, Depth: {this.props.depth}
</div>
{this.props.depth < 5 && (
<Node selected={this.state.selected} depth={this.props.depth + 1} />
)}
</>
);
}
}
树中的节点应该在单击时是可选的,我也希望(递归)在所有子级中切换选定状态。我以为可以通过将this.state.selected
通过道具传递给一个或多个孩子来做到这一点,不幸的是,这似乎不起作用。
子级被重新渲染,但是使用旧状态(可以理解,因为它们没有通过构造函数重新初始化)。处理该问题的正确方法是什么?
我也尝试过将key
属性传递给节点,以帮助做出反应以区分元素,但无济于事。
编辑:这是一些期望行为的示例:
考虑这棵树:
[ ] Foo
[ ] Foo A
[ ] Foo A1
[ ] Foo A2
[ ] Foo B
[ ] Foo B1
[ ] Foo B2
检查“ Foo”节点时的预期结果:
[x] Foo
[x] Foo A
[x] Foo A1
[x] Foo A2
[x] Foo B
[x] Foo B1
[x] Foo B2
检查“ Foo A”节点时的预期结果:
[ ] Foo
[x] Foo A
[x] Foo A1
[x] Foo A2
[ ] Foo B
[ ] Foo B1
[ ] Foo B2
向正确方向提供的任何提示/提示都值得赞赏。
您应该这样使用getDerivedStateFromProps
:
constructor(props) {
super(props);
this.state = {
selected: props.selected,
propsSelected: props.selected
};
this.toggleSelected = this.toggleSelected.bind(this);
}
static getDerivedStateFromProps(props, state) {
if (props.selected !== state.propsSelected)
return {
selected: props.selected,
propsSelected: props.selected
};
}
[每当遇到更改并因此更新状态时,我们总是将prevProp存储在状态中。