Call child method from parent

I have two components.

  1. Parent component
  2. Child component

I was trying to call child's method from Parent, I tried this way but couldn't get a result

class Parent extends Component {
  render() {
    return (
      <Child>
        <button onClick={Child.getAlert()}>Click</button>
      </Child>
      );
    }
  }

class Child extends Component {
  getAlert() {
    alert('clicked');
  }

  render() {
    return (
      <h1 ref="hello">Hello</h1>
    );
  }
}

Is there a way to call child's method from the parent ?

Note: Child and Parent components are in two different files

Answers 1

  • First off, let me express that this is generally not the way to go about things in React land. Usually what you want to do is pass down functionality to children in props, and pass up notifications from children in events (or better yet: dispatch).

    But if you must expose an imperative method on a child component, you can use refs. Remember this is an escape hatch and usually indicates a better design is available.

    Previously, refs were only supported for Class-based components. With the advent of React Hooks, that's no longer the case

    Using Hooks and Function Components (>= [email protected])

    const { forwardRef, useRef, useImperativeHandle } = React;
    
    // We need to wrap component in `forwardRef` in order to gain
    // access to the ref object that is assigned using the `ref` prop.
    // This ref is passed as the second parameter to the function component.
    const Child = forwardRef((props, ref) => {
    
      // The component instance will be extended
      // with whatever you return from the callback passed
      // as the second argument
      useImperativeHandle(ref, () => ({
    
        getAlert() {
          alert("getAlert from Child");
        }
    
      }));
    
      return <h1>Hi</h1>;
    });
    
    const Parent = () => {
      // In order to gain access to the child component instance,
      // you need to assign it to a `ref`, so we call `useRef()` to get one
      const childRef = useRef();
    
      return (
        <div>
          <Child ref={childRef} />
          <button onClick={() => childRef.current.getAlert()}>Click</button>
        </div>
      );
    };
    
    ReactDOM.render(
      <Parent />,
      document.getElementById('root')
    );
    <script src="https://unpkg.com/[email protected]/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/[email protected]/umd/react-dom.development.js" crossorigin></script>
    
    <div id="root"></div>

    Documentation for useImperativeHandle() is here:

    useImperativeHandle customizes the instance value that is exposed to parent components when using ref.

    Using Class Components (>= [email protected])

    const { Component } = React;
    
    class Parent extends Component {
      constructor(props) {
        super(props);
        this.child = React.createRef();
      }
    
      onClick = () => {
        this.child.current.getAlert();
      };
    
      render() {
        return (
          <div>
            <Child ref={this.child} />
            <button onClick={this.onClick}>Click</button>
          </div>
        );
      }
    }
    
    class Child extends Component {
      getAlert() {
        alert('getAlert from Child');
      }
    
      render() {
        return <h1>Hello</h1>;
      }
    }
    
    ReactDOM.render(<Parent />, document.getElementById('root'));
    <script src="https://unpkg.com/[email protected]/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/[email protected]/umd/react-dom.development.js" crossorigin></script>
    <div id="root"></div>

    Legacy API (<= [email protected])

    For historical purposes, here's the callback-based style you'd use with React versions before 16.3:

    const { Component } = React;
    const { render } = ReactDOM;
    
    class Parent extends Component {
      render() {
        return (
          <div>
            <Child ref={instance => { this.child = instance; }} />
            <button onClick={() => { this.child.getAlert(); }}>Click</button>
          </div>
        );
      }
    }
    
    class Child extends Component {
      getAlert() {
        alert('clicked');
      }
    
      render() {
        return (
          <h1>Hello</h1>
        );
      }
    }
    
    
    render(
      <Parent />,
      document.getElementById('app')
    );
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
    
    <div id="app"></div>


Sorry, you do not have a permission to answer to this question.