Component cannot be used as a JSX component. Its return type 'Element[]' is not a valid JSX element
Matthew C.
—When using a React node, or a React framework such as Next.js, with TypeScript you may get the following TypeScript error:
error TS2786: 'ListItems' cannot be used as a JSX component. Its return type 'Element[]' is not a valid JSX element. Type 'Element[]' is missing the following properties from type 'ReactElement<any, any>': type, props, key
For example, the following component may cause this error if you are using a version of TypeScript before version 5.1:
const todos = [ { id: 1, text: "clean the house" }, { id: 2, text: "buy milk" } ]; function ListItems(): JSX.Element[] { return todos.map((todo) => <li key={todo.id}>{todo.text}</li>); } export default ListItems;
The error occurs when the component is rendered:
<ul> <ListItems /> </ul>
A React component must return a React node. A React node can be one of the following:
<div />
JSX elementnull
, or undefined
value that’s not displayedNote that you can return an array of elements from a component’s render
method only if you are using React version 16.
The error occurs in TypeScript versions before version 5.1 that checks if React components return JSX elements of type JSX.Element
, which is only one of the possible types that can be returned from a React function component. Returning an array of JSX Elements will cause the type error.
You’ll also get a related error in older TypeScript versions if you change the return type of the ListItem
component from JSX.Element[]
to React.ReactNode
:
const todos = [ { id: 1, text: "clean the house" }, { id: 2, text: "buy milk" } ]; function ListItems(): React.ReactNode { return todos.map((todo) => <li key={todo.id}>{todo.text}</li>); } export default ListItems;
You’ll get the following error:
error TS2786: 'ListItems' cannot be used as a JSX component. Its return type 'ReactNode' is not a valid JSX element. Type 'undefined' is not assignable to type 'Element | null'.
This error occurs because React.ReactNode
includes things that aren’t JSX elements as React nodes can be more than JSX elements, as seen in the list above.
Here are two ways to fix the error:
You can wrap your returned elements in a React fragment to achieve this without adding extra nodes to the DOM:
function ListItems(): JSX.Element { return ( <> {todos.map((todo) => ( <li key={todo.id}>{todo.text}</li> ))} </> ); }
You also need to change the return type of the function from JSX.Element[]
to JSX.Element
.
If possible, update TypeScript to version 5.1+ so that TypeScript correctly checks if your component returns a valid React node. The version 5.1 release of TypeScript added a new JSX.ElementType
to check if a React component returns a valid React node.
Tasty treats for web developers brought to you by Sentry. Get tips and tricks from Wes Bos and Scott Tolinski.
SEE EPISODESConsidered “not bad” by 4 million developers and more than 100,000 organizations worldwide, Sentry provides code-level observability to many of the world’s best-known companies like Disney, Peloton, Cloudflare, Eventbrite, Slack, Supercell, and Rockstar Games. Each month we process billions of exceptions from the most popular products on the internet.