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.
