How do i listen to children events in parent component?
Look at my code what i am trying to achieve.
Page Component
interface PageProps {}
const Page: FC<PageProps> = ({}) => {
//I don't want to bind handlers here and bind it to Parent.
return (
<div>
<Parent>
<>
<Child />
<Child />
<Child />
<Child />
</>
</Parent>
</div>
)}
export default Page;
Child Component
import { FC } from 'react';
import AnotherChild from '../components';
interface IProps {
handleChange?: (value: string) => void;
}
const Child: FC<IProps> = ({ handleChange }) => {
//Methods
const onChange = (value: string) => {
handleChange ? handleChange(value) : null;
}
return (
<div>
<AnotherChild onChange={onChange} />
</div>
)
}
export default Child;
Parent Component
import React, { FC, Children, cloneElement, isValidElement } from 'react';
interface IProps {
children: React.ReactNode
}
const Parent: FC<IProps> = ({ children }) => {
//Methods
const handleChange = (value: string) => {
console.log("VALUE: ", value)
}
const arrChildren = Children.toArray(children);
return (
<div>
{
arrChildren.map((child, index) => {
return (
React.cloneElement(child, { handleChange: handleChange })
)
})
}
</div>
)
}
export default Parent;
So, I have children components which is emitting handleChange event, I want to listen those events in my <Parent />
component which is wrapped around.
Look at my <Page />
Component that is how those components will be called.
I have tried something you can look at my code but i am not getting those events.
Please help me to figure it out what i was doing wrong here.
Thank you
well, you did have the correct idea for listening to child events.
the problem is that you wrapped the child components inside a React.Fragment
.
I think you did that because of the type of child props. the witch says children: React.ReactNode
. change that to children: React.ReactNode | React.ReactNode[]
and then remove the fragment.
you should have something like this.
interface IProps {
handleChange?: (value: string) => void;
}
const Child: FC<IProps> = ({ handleChange }) => {
const onChange = (value: string) => {
handleChange ? handleChange(value) : null;
}
return (
<div>
<AnotherChild onChange={onChange} />
</div>
)
}
interface IProps {
children: React.ReactNode | React.ReactNode[]
}
const Parent: FC<IProps> = ({ children }) => {
const handleChange = (value: string) => {
console.log("VALUE: ", value)
}
const arrChildren = Array.isArray(children) ? children : [children];
return (
<div>
{
arrChildren.map((child, index) => {
return (
React.cloneElement(child, { handleChange: handleChange })
)
})
}
</div>
)
}
const Page: FC<PageProps> = ({}) => {
return (
<div>
<Parent>
<Child />
<Child />
<Child />
<Child />
</Parent>
</div>
)}