反应访问兄弟组件方法

时间:2017-07-25 09:31:48

标签: reactjs

使用React [15.6.1] Redux [3.7.2]和路由器[4.1.1] 我正在尝试访问属于其他(兄弟)组件的方法,但似乎无法访问它们。 无论如何要导出这些方法吗?

               ----------
               ¦ Parent ¦
               ----------
                   ¦
    -------------------------------
    ¦              ¦              ¦
-----------    -----------    -----------
¦ Child 1 ¦    ¦ Child 2 ¦    ¦ Child 3 ¦
-----------    -----------    -----------


// Child 1 has a method submitChild1()
// Child 2 has a method submitChild2()
// Child 3 has to access both of those methods


class Parent1 extends React.Component {

    render() {
        return (
            <div>
                <Child1 />
                <Child2 />
                <Child3 />
            </div>
        );
    }

}

class Child1 extends React.Component {

    submitChild1() {
        dispatch(Action1());
    }

    render() {...}

}

class Child2 extends React.Component {

    submitChild2() {
        dispatch(Action2());
    }

    render() {...}

}

class Child3 extends React.Component {

    submitTheOtherMethods() {
        // try to access Child 1 method
        // try to access Child 2 method
    }

    render() {...}

}

2 个答案:

答案 0 :(得分:3)

您无法做到这一点,您反对React的设计目的,这有助于确保组件设计良好,而不是与其他组件紧密耦合。

您需要在父级上定义方法,并将这些方法作为属性传递给子组件,如果您希望在多个不同组件之间共享方法。

如果需要在其中一个方法中调用方法,生命周期钩子仍然可以访问组件属性。

答案 1 :(得分:0)

您可以实现此行为。当然,信息将必须通过同胞的共同祖先(父母)传递。您可以使用useRef挂钩来做到这一点,例如:

function App() {
  
  const child1Method_ref = React.useRef(null);
  
  return(
    <React.Fragment>
      <Child1
        child1Method_ref={child1Method_ref}
      />
      <Child2
        child1Method_ref={child1Method_ref}
      />
    </React.Fragment>
  );
}

function Child1(props) {

  const child1Method = React.useCallback(()=>{
    console.log('I am a Child 1 method!!!');
  },[]);
  
  React.useEffect(()=>{
    props.child1Method_ref.current = child1Method
  },[]);
  
  return(
    <div>I am Child 1 (I declared the method)</div>
  );

}

function Child2(props) {
  return(
    <React.Fragment>
      <div>I am Child 2</div>
      <button onClick={()=>props.child1Method_ref.current()}>
        Click to call Child 1 method from Child 2
      </button>
    </React.Fragment>
  );
}

ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"/>

这是它的工作方式:

  • useRef指向一个对象,该参考将在整个渲染器中保留。即:对象不会改变。在组件的整个生命周期中都可以访问同一对象。
  • 该对象child1Method_ref向下传递到Child1,并运行useEffect对其进行更新并将method存储在对象的current属性中。观察员:useRef对象实际上具有一个名为“当前”的属性。
  • Child2还通过props接收相同的对象,并且可以从Child1访问已存储到ref对象中的方法。
  • useCallback用于在渲染器之间为函数保留相同的引用。即:在这种情况下,功能保持不变(并非在每个渲染器上都重新创建)。