I want to pass event prop from Child to Parent, so when we click the button in Child component, state from Parent should be triggered.
Let's assume that we have two components, Parent
and Child
, but Child
will not be imported directly in Parent
, like this
export default function Parent() {
const [count, setCount] = useState(0);
const handleClick = num => {
setCount(current => current num);
};
return (
<div>
<Child handleClick={handleClick} />
<h2>Count: {count}</h2>
</div>
);
}
and it's very straitforward to pass prop in this case, but how to do when we have situation when Parent does not know which component will be passed as {children}
prop, like this:
export default function Parent({children}) {
const [count, setCount] = useState(0);
const handleClick = num => {
setCount(current => current num);
};
return (
<div>
{children}
</div>
);
}
and later we import some child component
<Parent>
<Child />
</Parent>
CodePudding user response:
You can use cloneElement
along with React.Children.map
. cloneElement
clones and returns a new React element using a given element as the starting point. You can add props, ref and keys on top.
React.Children.map
will invoke a function on every immediate child.
//function body
....
let newChildren = React.Children.map(children, (child) => React.cloneElement(child, { handleClick })
);
return (
<div>
{newChildren}
</div>
);
CodePudding user response:
This would couple parent to a child. children
property is specifically to make sure parent does not care what the child is.
Push the state & callback up the component hierarchy, to the component that knows specific types of both parent and child components.
const [count, setCount] = useState(0);
return (<Parent count={count}>
<Child onClick={num => setCount(count => count num} />
</Parent>);
CodePudding user response:
Simply, You can achieve this via cloneElement
like this.
export const Parent = ({children}) => {
const handleClick = () => {
console.log('okk')
}
return (
<div>
{ React.cloneElement(children, { handleClick} )}
</div>
)}
and now you are able to trigger handleClick
function from the child component.