You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中兄弟组件间传递对象的正确方式:组件方法传递方案咨询

How to Pass a Method Between Sibling React Components

Hey there! Coming from a C background, it makes total sense to think in terms of function pointers, but React has its own idiomatic way to handle this kind of component communication. Since PlanBuilder and PlanMenu are sibling components (both children of App), they can't directly call each other's methods—you need to use their parent component as a middleman. Here are two React-compliant solutions to get this working:

This is the React-preferred approach: move the shared state (objects) up to the parent App component, then pass both the state and the method to modify it down to the child components. This keeps state management centralized and follows React's unidirectional data flow principle.

Updated App.js

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { objects: [] };
    // Bind `this` to ensure the method works correctly in child components
    this.addObject = this.addObject.bind(this);
  }

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

  render() {
    return (
      <div className="App">
        {/* Pass the objects state to PlanBuilder for rendering */}
        <PlanBuilder objects={this.state.objects} />
        {/* Pass the addObject method to PlanMenu for triggering additions */}
        <PlanMenu addObject={this.addObject} />
      </div>
    );
  }
}

Updated PlanBuilder.js

class PlanBuilder extends React.Component {
  render() {
    return (
      <Stage>
        <Layer>
          {this.props.objects.map((object) => object.render())}
        </Layer>
      </Stage>
    );
  }
}

Updated PlanMenu.js

class PlanMenu extends React.Component {
  render() {
    return (
      <div className="PlanMenu">
        {/* Wrap the call in an arrow function to avoid immediate execution on render */}
        <button
          type="button"
          onClick={() => this.props.addObject(new CWall({ x: 100, y: 100, length: 200 }))}
        >
          Wall
        </button>
      </div>
    );
  }
}

Solution 2: Using Refs to Access Child Component Instance (For Simple Scenarios)

If you prefer not to lift state, you can use React refs to get a reference to the PlanBuilder instance, then pass its addObject method to PlanMenu. Note that this approach couples your components more tightly and breaks unidirectional flow, so use it sparingly.

Updated App.js

class App extends React.Component {
  constructor(props) {
    super(props);
    // Create a ref to hold the PlanBuilder instance
    this.planBuilderRef = React.createRef();
  }

  render() {
    return (
      <div className="App">
        <PlanBuilder ref={this.planBuilderRef} />
        {/* Pass a wrapper function that calls PlanBuilder's addObject */}
        <PlanMenu addObject={(obj) => this.planBuilderRef.current.addObject(obj)} />
      </div>
    );
  }
}

PlanMenu.js remains the same as in Solution 1

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

Critical Note

Your original PlanMenu code had a bug: onClick={addObject(new CWall(...))} calls the function immediately when the component renders, not when the button is clicked. Wrapping the call in an arrow function (as shown above) fixes this by ensuring the function only runs on click.

内容的提问来源于stack exchange,提问作者kasom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 00:27:32