Use generics in React to make dynamic and flexible components

You might be used to using generics with functions but you can also use them with react components.

So here this Table component takes in an array of items which I've currently typed as just id: string and then it also takes a function to render the item which says item: {id: string}


interface TableProps {
items: { id: string }[]
renderItem: (item: { id: string }) => React.ReactNode
}
export const Table = (props: TableProps) => {
return null
}

What you want here is to be able to pass in any items and for that id string to then propagate through to the renderItem. You might try the following, using TItem, but this actually isn't valid.


export const Table = <TItem>(props: TableProps) => {
return null
}

What you need to do instead is you need to turn this Table into a standard function.


export function Table<TItem>(props: TableProps) {
return null
}

We need to make TableProps generic as well with TItem. Remember to use TItem in the items array and the renderItem function.


interface TableProps<TItem> {
items: TItem[]
renderItem: (item: TItem) => React.ReactNode
}
export function Table<TItem>(props: TableProps<TItem>) {
return null
}

And now anything we put in the Component props items will be propagated through to our item because it's generic.

If we ever want to pass the generic manually we specificy it with our Table instance. Now the example below will error out since id should be a number not a string.


const Component = () => {
return (
<Table<{ id: number }>
items={[{ id: "1", name: "Matt" }]}
renderItem={(item) => <div>{item.id}</div>}
></Table>
)
}

So it's a funny syntax and not a lot of people know about it. I kind of stumbled on it by accident and every time. But, every time I use it I think, "wow that's pretty cool!"

Transcript

0:00 You might be used to using generics with functions, but you can also use them with React components. Here, this Table component, it takes in an array of items, which have currently time to just ID String. Then it also takes a function to render the item, which says Item ID String.

0:16 Actually, what you want here is you want to be able to parse in any items. For that ID String to then propagate through to the renderItem here. We can do that. You can make a item here, which would be, lets say, tItem. You might be put off by the fact that inside this TSX file, this syntax actually isn't valid.

0:36 What you need to do instead is you need to turn this table into a function, which looks like this, and remove the arrow. Now, you're allowed to use it. Here, we probably need to make this generic as well, tItem. Let's add tItem up here.

0:51 We can take the ID String and just put tItem in there. Anything we put into here, name, Matt, for instance, will be propagated through to our item because it's generic. If we ever want to pass the generic manually and specify it, then we can pass it here. We can say, "ID equals a number," for instance.

1:10 This will array because it's not passing that. It's a funny syntax. Not a lot of people know about it. I stumbled on it by accident. Every time I use it, I think, "Wow, that's pretty cool."

You can use generics in React to make incredibly dynamic, flexible components. Here, I make a Table component with a generic 'items' type.

Discuss on Twitter

More Tips

Assign local variables to default generic slots to dry up your code and improve performance