Advanced Props 12 exercises

What's The Difference Between React.ReactNode and React.FC?

There are a couple of different solutions that both rely on understanding the ReactNode type.

interface TableProps {
renderRow: React.ReactNode

A Closer Look at ReactNode

If we command click on ReactNode in local VS Code, it will take us to the definition of the typ

Loading solution


00:00 There are a couple of different solutions here, but they all rely on understanding this React node type here. If we command click on it, which takes us to the definition of the type, we end up in types React here. And we see that React node here is not quite what we thought it was. React node doesn't represent a component,

00:19 it actually represents a member of JSX or a thing that you can render in React. So we have React element, string, number, React fragment, React portal, Boolean null or undefined. All of these things you can pass into a div, let's say. So if we were to just say like div and then props.renderRow,

00:38 this actually is correct because React.ReactNode represents the thing that gets put into JSX. So again, just to really firm this up, let's say const component and React.ReactNode, and we can put inside here

00:55 anything that we can pass into this section there. So we've got our component React.ReactNode, we can put null in there, we can put undefined in there, one, two, three, like numbers we can put in there. We can't pass objects into there because that's not a part of React node basically.

01:14 So now we need to understand that this renderRow function isn't quite doing what we want because React.ReactNode is not a function. We can change this by making it a function that returns a React.ReactNode. Except now, if we take a look down here,

01:32 this index, like we're expecting to receive an index here, which is going to go into our div here. So let's say we've got index and let's make it a number. Now the errors below go away because we've properly represented what we're trying to do here. So renderRow, this should be an error

01:51 because we should need to pass a function into here. So React.ReactNode doesn't represent a component, it actually represents a thing that gets returned from a component. Now you may be looking at this and thinking, I wonder if there's like a type within React itself that can help me out here. And there is.

02:10 This is React.fc, which is React.FunctionalComponent. Now this type is kind of relatively controversial and, or at least it was for a long time. But since TypeScript 5.1, which is, as I record this, the current version of TypeScript,

02:27 then React.fc has actually gotten a lot better. And if we take a look at it by just command-clicking on fc, you can see that it's an alias for FunctionComponent. Lovely. FunctionComponent is right here. And this is an interface which describes a function. And we can see that this is an interface that describes a function with this

02:45 because this is a call signature for this interface. Slightly complicated syntax. But what we can see is that it takes in props, p, and context, any, this is like an old sort of React API, and it returns, hey, our friend, a React node.

03:01 So this is basically an alias over the top of this solution, which was our previous one here, indexNumberReact.ReactNode, by just using a slightly more terse syntax. And you also get a couple of extra things here. So you've got props.renderRow. You've also got access to displayName, if you need that.

03:22 And you've got access to default props, context types. I think context types and default props are going away, possibly. But displayName is very occasionally useful. But essentially, React.fc just gives you a way to express a function that can return a React.ReactNode. And I'll link some more materials below

03:41 that I've written publicly on my opinion about React.fc. Really, I think I actually just prefer this syntax for a couple of other reasons, which we'll go into when we cover forward ref. But this just makes it really, really clear what's happening, and you're gonna be using React.ReactNode a lot,

03:59 because you're gonna be using it to type children as well, which I covered in previous, I think in the beginners React tutorial. So there you go. This is the difference between React.ReactNode, thinking of it as a component, and thinking of it as something that JSX returns,

04:14 or that represents JSX.