React FCの型についての話。
Reactでコンポーネントを書くとき、
type Props = { title: string }
const App: React.FC<Props> = ({ children, ...props }) => {
return (
<>
<p>{props.title}</p>
{children}
</>
)
}
上記のようにFunction Componentで型はReact.FC、ジェネリクスで別途定義したPropsの型を渡す〜っていうのがよく見る書き方だと思ってる。
ただ、最近React.FCを使わないという記事が目に入るようになった。
どうやらReact.FCだと暗黙的にchildrenを受け取ってしまっているので、必要不必要関係なしに渡せる受け取れるのが問題らしい。
代わりにReact.VFCというchildrenが定義されてない型を使うことを推奨してる人が多い。VはvoidのV。
ちなみに手元にあった @types/react v17.0.4時点でのReact.FCの型定義は下記。
type FC<P = {}> = FunctionComponent<P>;
interface FunctionComponent<P = {}> {
(props: PropsWithChildren<P>, context?: any): ReactElement<any, any> | null;
propTypes?: WeakValidationMap<P>;
contextTypes?: ValidationMap<any>;
defaultProps?: Partial<P>;
displayName?: string;
}
type PropsWithChildren<P> = P & { children?: ReactNode };
childrenが暗黙的にReactNodeで定義してある。
VFCはこんな感じ。
type VFC<P = {}> = VoidFunctionComponent<P>;
interface VoidFunctionComponent<P = {}> {
(props: P, context?: any): ReactElement<any, any> | null;
propTypes?: WeakValidationMap<P>;
contextTypes?: ValidationMap<any>;
defaultProps?: Partial<P>;
displayName?: string;
}
propsがPropsWithChildrenでないこと以外同じっぽい。
つまりVFCで冒頭のコードを書く際はこうなる。
type Props = {
title: string
children: ReactNode // 使うときだけ定義
}
const App: React.VFC<Props> = ({ children, ...props }) => {
return (
<>
<p>{props.title}</p>
{children}
</>
)
}
ただ、将来的にはFCからも暗黙的にchildrenが定義されなくなるらしい。
個人的なまとめ
正直FCで定義されてるchildrenってoptionalだし…FC→VFCにしてバージョンアップのタイミングでVFC→FCに置き換えるコストを考えると、「FCのままchildrenを使うパターンのみ定義」が一番カロリー少なくていいかなと思ったり(諸説あり)
参考にさせていただいた記事。
この記事が気に入ったらサポートをしてみませんか?