Use React.ReactNode for the children prop in React TypeScript components and Render Props

Shawn Wang
InstructorShawn Wang

Share this video with your friends

Send Tweet
Published 3 years ago
Updated 2 years ago

Because @types/react has to expose all its internal types, there can be a lot of confusion over how to type specific patterns, particularly around higher order components and render prop patterns. The widest and most recommended element type is React.ReactNode, and we build up to it by explaining the edge cases.

Instructor: [00:00] Even though we may not always be typing every single prop ourselves, it's useful to talk about the children prop because it helps us understand the underlying React types.

[00:13] For example, if I wanted to refactor my button component with a string label to accept things other than strings, I would have to add additional types like so.

[00:25] One way to figure out what type to add is actually to just go ahead and use the type and let the compiler suggest to you what types it needs. Over here, it's saying type element is not assignable to string, so therefore, we're giving it an element. It's not accepting it because it expects a string.

[00:49] What if we just did a union type with element? That actually does work. What if we wanted to use React's composition model instead of a whole bunch of props?

[01:02] For example, we can refactor this and no longer use the label prop and put our div as a child of the button. There is no longer a label prop, so we have to name this children and accordingly lay down props.children and this also works.

[01:28] However, what happens if we try to have multiple children? Well this happens. In order to solve that we can make this element into an array.

[01:42] In fact, there are a number of different ways to type children and the auto-complete will suggest a whole bunch of different things.

[01:49] For example, you can have React.ReactChild which is functionally the same as string and JSX Element as an array.

[01:57] If you choose to type it with the type that's actually named React's React children, it will fail to compile because React's Reach children is meant as a utility for iterating through children and not for typing React children. All in all, the safest rule of thumb is to type children with React.ReactNode.

[02:24] Even then, it's not the be all and end all situation. If you're trying to write a render prop and expect your children to be used as a function of a child, you're going to have to change accordingly. Now you can use function as a child.