嵌套组件未更新其状态

ccK*_*Kep 5 javascript components reactjs

我在更新树形结构中的嵌套组件时遇到了一些麻烦。我创建了以下最小示例来说明问题: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} />
        )}
      </>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

单击时应该可以选择树中的节点,我也希望(递归地)在所有子级中切换选定状态。我以为我可以通过将this.state.selected道具传递给一个或多个孩子来做到这一点,不幸的是,这似乎不起作用。

子级会被重新渲染,但是会使用其旧状态(可以理解,因为它们没有通过构造函数重新初始化)。处理此问题的正确方法是什么?

我尝试过将key道具传递给节点,以帮助做出反应以区分元素,但无济于事。

编辑:这是所需行为的一些示例:

考虑这棵树:

[ ] Foo
    [ ] Foo A
        [ ] Foo A1
        [ ] Foo A2
    [ ] Foo B
        [ ] Foo B1
        [ ] Foo B2
Run Code Online (Sandbox Code Playgroud)

检查“ Foo”节点时的预期结果:

[x] Foo
    [x] Foo A
        [x] Foo A1
        [x] Foo A2
    [x] Foo B
        [x] Foo B1
        [x] Foo B2
Run Code Online (Sandbox Code Playgroud)

检查“ Foo A”节点时的预期结果:

[ ] Foo
    [x] Foo A
        [x] Foo A1
        [x] Foo A2
    [ ] Foo B
        [ ] Foo B1
        [ ] Foo B2
Run Code Online (Sandbox Code Playgroud)

朝着正确方向的任何提示/提示都值得赞赏。

sud*_*ngh 3

你应该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
          };
      }
Run Code Online (Sandbox Code Playgroud)

我们总是将 prevProp 存储在 state 中。每当我们遇到存储在状态中的道具和来自父组件的道具发生变化时,我们都会更新selected由父组件和组件本身控制的状态部分(),并且我们还会在状态中保留此时的道具用于将来的差异。

通常,可以从父组件和自身控制的组件将涉及这种逻辑。大多数 React 组件库中的输入组件就是一个理想的例子。