代码之家  ›  专栏  ›  技术社区  ›  SkyeBoniwell

在父组件中设置状态,以便子组件可以访问状态

  •  1
  • SkyeBoniwell  · 技术社区  · 6 年前

    我正在尝试为我的网络游戏设置一个允许玩家上传怪物照片的状态。

    我有一个名为 <MonsterContainer> 是的。它包含两个子组件: <MonsterPortraitUpload> <MonsterViewer>

    我正在设置状态 <怪物集装箱>

    <怪物肖像上传> 将允许用户上传照片,它将添加到怪物肖像数组中的状态。

    <怪物查看器> 将显示阵列中怪物的所有照片。

    如何确保我的两个子组件可以访问此状态?

    以下是我现在拥有的:

    class MonsterContainer extends Component {
    
    constructor() {
        super();
        this.state = {
            MonsterPortraits: []
        };
    }
    
    render() {
        const { monsterId } = this.props;
        return (
            <div>
                <div>
                    <MonsterPortraitUpload monsterId={monsterId}/>
                </div>
                <div>
                    <MonsterViewer monsterId={monsterId}/>
                </div>
            </div>
        );
    }
    }
    

    现在我正试图将状态写入 <怪物查看器> 但我有个错误:

    uncaught typeerror:无法读取null的属性“monstercriptions”

    2 回复  |  直到 6 年前
        1
  •  2
  •   Dave Newton    6 年前

    子组件 不要 有权访问父状态;数据单向流动:向下。

    如果子组件需要访问父状态,则应将该状态作为属性传递。

    如果这不足以满足您的需要(例如,一个嵌套很深的层次结构,其中的子级需要更新更高级别的状态),那么您可能需要一个不同的状态管理系统,例如redux/etc。

    在你的情况下,如图所示,把一系列肖像传给 <MonsterView /> 就足够了,而且 <MonsterPortraitUpload /> 将采用添加到容器状态的函数属性(例如,添加肖像)。

    这是react和类似软件中的一个基本概念:哑组件、智能容器。转储组件获取数据和函数,容器管理状态。这会在深层层次结构中分解,因为最终必须将属性传递到多个级别。

    那个 可以 通过react上下文寻址,或者将属性注入克隆的子级,等等,但是这些是否是好的解决方案取决于您的体系结构。一般来说,不同形式的状态管理可以通过引入一个复杂的层来解决这样的问题。

    要修改容器的状态,需要传递一个hander;非常方便:

    class MonsterContainer extends Component {
      // Etc.
    
      addPortrait(someData) {
        this.setState([ ...this.state.MonsterPortraits, someData ]);
      }
    
      render() {
        // Etc.
        <MonsterPortraitUpload addHandler={this.addPortrait} /> 
    

    <怪物肖像上传/> 但是,您可以创建数据(例如表单),然后在用户操作(例如,按钮按下)上调用容器的处理函数来传递任何数据:

    class MonsterPortraitUpload extends Component {
      addPortait() {
        // Marshall the data however, then
        this.props.addPortrait(newData);
      }
      // Etc.
    }
    
        2
  •  1
  •   Sasha Kos    6 年前

    您显示的错误,绝对不是来自附加代码。 如果你想把状态传下去用这个

    class MonsterContainer extends Component {
      constructor() {
          super();
          this.state = {
              MonsterPortraits: []
          };
      }
    
      render() {
        return (
            <div>
                <div>
                    <MonsterPortraitUpload monsterPortraits={this.state.MonsterPortraits}/>
                </div>
                <div>
                    <MonsterViewer monsterPortraits={this.state.MonsterPortraits}/>
                </div>
            </div>
        );
      }
    }
    

    所以在 MonsterPortraitUpload 可以使用的组件 this.props.monsterPortraits