TypeScript React の FC
, VFC
という型は過渡期で将来的に変更になる可能性があるからコンポーネントの返す型は JSX.Element
にした方が良いという記事を読んで新しいプロジェクトでは JSX.Element
を使うようにしたのですが、そこでハマったことのメモ
null を返せない
条件によって表示したくないようなコンポーネントで null
を返したりしていましたが、JSX.Element
は null
を含まないようです
const ComponentVFC: VFC = () => { return null; }; // => OK const ComponentJsxElement = (): JSX.Element => { return null; }; // => Type 'null' is not assignable to type 'Element'.
Return type を JSX.Element | null
にすれば OK
- const ComponentJsxElement = (): JSX.Element => { + const ComponentJsxElement = (): JSX.Element | null => { return null; }; // => OK
VFC も JSX.Element も Array.map を直接返せない
リストの中身の作成だけ別関数に出してしまいたい様な場合。
VFC は大丈夫な気がしてたけど記憶違いでした。
const list = ['ichigo', 'aoi', 'ran']; const ListVFC: VFC = () => { return list.map((item) => <span key={item}>{item}</span>); }; // => Type 'Element[]' is missing the following properties from type 'ReactElement<any, any>': type, props, key const ListJsxElement = (): JSX.Element => { return list.map((item) => <span key={item}>{item}</span>); }; // => Type 'Element[]' is not assignable to type 'Element'.
JSX.Element[] はコンポーネントとして扱えないので、純粋な関数として定義して使う
🙅 コンポーネント扱いできない
const list = ['ichigo', 'aoi', 'ran']; const ListItem = (): JSX.Element[] => { return list.map((item) => <span key={item}>{item}</span>); }; const Component = (): JSX.Element => { return <div><ListItem /></div>; }; // => 'ListItem' cannot be used as a JSX component. // => Its return type 'Element[]' is not a valid JSX element.
🙆
const list = ['ichigo', 'aoi', 'ran']; const listItems = (): JSX.Element[] => { return list.map((item) => <span key={item}>{item}</span>); }; const Component = (): JSX.Element => { return <div>{listItems()}</div>; };
所管
勘違いしてた部分も振り返れたので良かった。
[参考]
- 【検証】React.FC と React.VFC はべつに使わなくていい説 – KRAY Inc.
- reactjs - Type 'Element[]' is missing the following properties from type 'Element': type, props, key - Stack Overflow
- reactjs - Type '(props: Props) => Element[]' is not assignable to type 'FunctionComponent<Props>' - Stack Overflow
- 一番文句言われなさそうな React コンポーネントの書き方