繁体   English   中英

React 兄弟组件之间交换对象的正确方式

[英]The proper way of exchanging objects between sibling components in React

我正在尝试构建一个简单的 React 应用程序,但遇到了麻烦。 我有以下结构:

应用程序.js

class App extends React.Component {
  render() {
    return (
      <div className="App">
        <PlanBuilder />
        <PlanMenu />
      </div>
    );
  }
}

计划菜单.js

class PlanMenu extends React.Component {
  render() {
    return (
      <div className="PlanMenu">
        <button type="button"
          onClick={addObject(
            new CWall({
                x: 100,
                y: 100,
                length: 200
            }))}>Wall
        </button>
      </div>
    );
  }
}

计划建造者.js

class PlanBuilder extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      objects: []
    };
  }

  addObject(object) {
    this.setState({
        objects: [...this.state.objects, object]
    });
  }

  render() {
    return (
      <Stage>
        <Layer>
          {
          this.state.objects.map(function(object) {
              return object.render();
            })
          }
        </Layer>
      </Stage>
    );
}

所以主要的想法是我有两个兄弟组件:绘图区域和菜单。 当菜单上的按钮被按下时,我想创建一个新对象并将其发送到绘图区域元素。 所以,问题是如何将PlanBuilder.addObject方法传递给PlanMenu类。 我来自 C 世界,我想到的是将PlanMenu函数指针传递给PlanMenu 但是,我不确定这是一个合适的解决方案。 你能推荐我在 React 中执行此操作的正确方法吗? 先感谢您。

在这种情况下,您有两种方法。

更简单的一种是将您在 PlanBuilder 上的逻辑移动到 App,并将必要的道具传递给 PlanBuilder 和 PlanMenu,例如:

class PlanMenu extends React.Component {
  render() {
    const { addObject } = this.props

    return (
      <div className="PlanMenu">
        <button type="button"
          onClick={addObject(
            new CWall({
                x: 100,
                y: 100,
                length: 200
            }))}>Wall
        </button>
      </div>
    );
  }
}

class PlanBuilder extends React.Component {
  render() {
    const { objects } = this.props

    return (
      <Stage>
        <Layer>
          {objects.map(function(object) {
            return object.render();
          })}
        </Layer>
      </Stage>
    )
  }
}

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      objects: []
    };

    this.addObject = this.addObject.bind(this)
  }

  addObject(object) {
    this.setState({
        objects: [...this.state.objects, object]
    });
  }

  render() {
    const { objects } = this.state

    return (
      <div className="App">
        <PlanBuilder objects={objects} />
        <PlanMenu addObject={this.addObject} />
      </div>
    );
  }
}

另一种选择是创建一个“容器”来保存逻辑而不是将其添加到 App,例如:

class PlanMenu extends React.Component {
  render() {
    const { addObject } = this.props

    return (
      <div className="PlanMenu">
        <button type="button"
          onClick={addObject(
            new CWall({
                x: 100,
                y: 100,
                length: 200
            }))}>Wall
        </button>
      </div>
    );
  }
}

class PlanBuilder extends React.Component {
  render() {
    const { objects } = this.props

    return (
      <Stage>
        <Layer>
          {objects.map(function(object) {
            return object.render();
          })}
        </Layer>
      </Stage>
    )
  }
}

class PlanContainer extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      objects: []
    };

    this.addObject = this.addObject.bind(this)
  }

  addObject(object) {
    this.setState({
        objects: [...this.state.objects, object]
    });
  }

  render() {
    const { objects } = this.state

    return (
      <div>
        <PlanBuilder objects={objects} />
        <PlanMenu addObject={this.addObject} />
      </div>
    )
  }
}

class App extends React.Component {

  render() {
    return (
      <div className="App">
        <PlanContainer />
      </div>
    );
  }
}

在我看来,创建一个 Container 会让你的代码更具可读性、可重用性和更干净:)

希望有帮助!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM