3
votes

I have this:

import React, { useReducer } from 'react';
import { Item, List } from '../Types';

type Props = {
    items: List;
};

const TodoList: React.SFC<Props> = ({ items, children }) => {
    return items.map((item: Item) => <div key={item.id}>{item.id}</div>);
};

export default TodoList;

I keep getting:

Type '({ items, children }: PropsWithChildren) => Element[]' is not assignable to type 'FunctionComponent'. Type 'Element[]' is missing the following properties from type 'ReactElement ReactElement Component)> | null) | (new (props: any) => Component)>': type, props, key

2

2 Answers

4
votes

The issue is that you are trying to return an array of elements in your JSX. In React, you can only return a single parent element which then needs to wrap the rest of your elements. So try changing

return items.map((item: Item) => <div key={item.id}>{item.id}</div>);

to

return (
    <div>
        {items.map((item: Item) => <div key={item.id}>{item.id}</div>)}
    </div>
)

If you would prefer not to have the extra div, you can also wrap your list items with a Fragment. In that case, you would do:

return (
    <React.Fragment>
        {items.map((item: Item) => <div key={item.id}>{item.id}</div>)}
    </React.Fragment>
)
0
votes

This is type definition of SFC: it expects you to return a ReactElement or null, while you are returning Element[].

type SFC<P = {}> = FunctionComponent<P>;

interface FunctionComponent<P = {}> {
  (props: PropsWithChildren<P>, context?: any): ReactElement | null;
  ...
}

You can use React fragments:

const TodoList: React.SFC<Props> = ({ items, children }) => {
  return (
    <>
      {items.map((item: Item) => (
        <div key={item.id}>{item.id}</div>
      ))}
    </>
  );
};