What happens when we pass in children in React? Children is a special prop that allows us to pass in any type of element. It could be a number, a string, a boolean, an array of elements or even another component. So how can we check the types?
Of course we could define it as any which is basically the same as just not having type checking which defeats the whole purpose of using Typescript.
There are a couple of types we could choose from:
JSX.Element
Children must be a single JSX element. Doesn't allow multiple children, or strings etc.
type ButtonProps = {
children: JSX.Element
}
const Button = ({ children }: ButtonProps) => <button>{children}</button>
export function Card() {
return (
<Button>
<span>Click me</span>
</Button>
)
}
JSX.Element[]
Allows multiple JSX elements but no strings, numbers etc
type ButtonProps = {
children: JSX.Element[]
}
const Button = ({ children }: ButtonProps) => <button>{children}</button>
export default function Card() {
return (
<Button>
<span>click me</span>
<i>svg icon</i>
</Button>
)
}
JSX.Element | JSX.Element[]
Allows single or multiple JSX elements but no strings, numbers etc
type ButtonProps = {
children: JSX.Element | JSX.Element[]
}
const Button = ({ children }: ButtonProps) => <button>{children}</button>
export default function Card() {
return (
<Button>
<span>click me</span>
</Button>
)
}
export default function Card2() {
return (
<Button>
<span>click me</span>
<i>svg icon</i>
</Button>
)
}
React.ReactChild
Allows one React element, string or number
type ButtonProps = {
children: React.ReactChild
}
const Button = ({ children }: ButtonProps) => <button>{children}</button>
export default function Card() {
return <Button>click me</Button>
}
React.ReactChild[]
Allows multiple React elements, strings or numbers
type ButtonProps = {
children: React.ReactChild
}
const Button = ({ children }: ButtonProps) => <button>{children}</button>
export default function Card() {
return (
<Button>
click me
<i>svg icon</i>
</Button>
)
}
React.ReactChild | React.ReactChild[]
Allows single or multiple React elements, strings or numbers
type ButtonProps = {
children: React.ReactChild
}
const Button = ({ children }: ButtonProps) => <button>{children}</button>
export default function Card() {
return <Button>click me</Button>
}
export default function Card2() {
return (
<Button>
click me
<i>svg icon</i>
</Button>
)
}
React.ReactNode
Allows multiple children, strings, numbers, fragments, portals... We could use the above example but it is a little verbose and ReactNode covers a little more.
type ButtonProps = {
children: React.ReactNode
}
const Button = ({ children }: ButtonProps) => <button>{children}</button>
export default function Card() {
return (
<Button>
click me
<i>svg icon</i>
</Button>
)
}
Conclusion
And that's it, you now have no excuses for adding type checking for your children.
Top comments (12)
Hi Debbie,
Here is how I play with children:
FC
already acceptschildren
, no need forPropsWithChildren
.If you don't want want
children
, you can useVFC
.This is no longer true for
FC
with React 18. You must either usePropsWithChildren
or explicitly add achildren
prop to your type definition.you're right. thanks for the comment.
Thank you Aniello! Good to know.
thanks guys, will play around with it
Nice article! There is only a small mistake on the last example where it reads
children: React.ReactChild
instead ofchildren: React.ReactNode
ooops. thanks just corrected it. nice catch
Hi Debbie, just came across this as it's missing from a number of courses I've used - a little surprising as React props are mentioned, but not the commonly used 'children' prop! Thanks for laying this out so clearly.
Thank you Debbie O'Brien, this post is great, i usually forget whats de diff between params type for children, this cheat post is Gold.
Thanks everyone.
Thank you Debbie, really usefull, short and clear article :)