sakshinarang
sakshinarang

Reputation: 99

How to call a Parent method in Child Component using Hook (ForwardRef concept only) when they are in same page

Scenario 1: Works fine

This is the ParentComponent

import React, { Children } from 'react'
import ChildComponent from './ChildComponent';
const ParentComponent = () => {
    const buttonRef = React.useRef({ focusHandler: () => alert("hi") });
  
    return (
      <div>
        <ChildComponent ref={buttonRef} />
      </div>
    );
  };
export default ParentComponent;

This is the Child Component using Forward Reference.

import React from 'react'

const ChildComponent = React.forwardRef((props, ref) => {
    return (
      <div>
        <button onClick={ref.current.focusHandler}>Focus Input</button>
      </div>
    );
  });
  
export default ChildComponent;

Scenario 2: Need help here

Now, what if, the ParentComponent doesn't ChildComponent and I wish to call the ChildComponent like so in the main page:

MainPage.js:

import React from 'react'
import ParentComponentScenario2 from './ParentComponentScenario2';
import ChildComponentScenario2 from './ChildComponentScenario2';

const MainPage = () => {
    return (
        <div>
            <ParentComponentScenario2>
                <ChildComponentScenario2 />
            </ParentComponentScenario2>
        </div>

    )
}

export default MainPage;

ParentComponentScenario2:

import React, { Children } from 'react'
const ParentComponentScenario2 = () => {
    const buttonRef = React.useRef({ focusHandler: () => alert("hi") });
  
    return (
      <div>
       {props.children};
      </div>
    );
  };
export default ParentComponentScenario2;

Query, how do I pass the method in ChildComponent now as <ChildComponent ref={buttonRef} /> isn't possible now on the page.

ChildComponentScenario2:

import React from 'react'

//How to implement onClick,  props.focusHandler doesn't seem to work for some reason either.
const ChildComponentScenario2 = () => {
  return (
    <div>
       <button onClick={props.focusHandler}>Focus Input</button>
    </div>
  )
}

export default ChildComponentScenario2;

Upvotes: 0

Views: 131

Answers (1)

Dennis Vash
Dennis Vash

Reputation: 53884

You need to "inject" properties using React.Children API and React.cloneElement:

const ParentComponent = ({ children }) => {
  const buttonRef = React.useRef({ focusHandler: () => console.log("ref") });
  const focusHandler = () => console.log("callback");

  return (
    <div>
      {React.Children.map(children, child =>
        React.cloneElement(child, { ref: buttonRef, focusHandler })
      )}
    </div>
  );
};

const ChildComponent = React.forwardRef(({ focusHandler }, ref) => {
  return (
    <div>
      <button onClick={ref?.current.focusHandler}>Ref</button>
      <button onClick={focusHandler}>Callback</button>
    </div>
  );
});

Edit wizardly-diffie-14yx5

Upvotes: 1

Related Questions