React composition - How to call parent method

Solution 1:

I recently had to do something similar and, inspired by this post, I ended up with:

const WrapperComponent = ({ children }) => {
  const myFunc = React.useCallback(() => {
    // ...
  }, []);
  
  return React.Children.map(children, (child) => {
    if (React.isValidElement(child)) {
      return React.cloneElement(child, { onClick: myFunc });
    }
  });
}

[edit] a working demo:

The following snippet demonstrate how the above approach could be used to read a child prop from the wrapper/parent component.
Please be aware that it might take a few seconds for the snippet to load and run; I did not investigate the reason for this, as it is out of the scope for the question.

const App = () => {
  return (
    <div>
      <h1>MyApp</h1>
      <WrapperComponent>
        <button id='btn1'>btn1</button>
        <button id='btn2'>btn2</button>
        <button id='btn3'>btn3</button>
        <div className='fakeBtn' id='div1'>div1</div>
      </WrapperComponent>
    </div>
  );
}

const WrapperComponent = ({ children }) => {
  const [clickedChildId, setClickedChildId] = React.useState();
  
  const myFunc = React.useCallback((id) => {
    setClickedChildId(id)
  }, [setClickedChildId]);
  
  React.useEffect(() => {
    clickedChildId && console.log(`the clicked child ID is ${clickedChildId}`);
  }, [clickedChildId]);
  
  return React.Children.map(children, (child) => {
    if (React.isValidElement(child)) {
      return React.cloneElement(child, { onClick: () => myFunc(child.props.id) });
    }
  });
  
}

ReactDOM.render(<App />, document.querySelector('#mountNode'))
div.fakeBtn {
  background-color: #cdf;
  padding: 5px;
  margin: 3px 0;
  border: 1px solid #ccc;
  border-radius: 2px;
}
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>

<div id='mountNode'></div>

Solution 2:

You can do it by cloning the children, and giving it the props that you want:

React.cloneElement(children, {calledByChild})

This way, you add the function calledByChild to the children, so you can call it from the children component.

It could look like this:

const Parent = ({ children }) => {
  const func = () => console.log("click in Parent");
  return (
    <>
      <div>children</div>
      {cloneElement(children, {func})}
    </>
  );
};

const Children = ({func}) => {
  return <button onClick={func}>Click</button>;
};

Take a look at this article