これはなに?
Reactでコンポーネントを定義するときによく出てくるReact.FC
とかReact.VFC
ってなんぞや?と思っていて、最近その答えがわかったので共有がてら書こうと思います。
結論
結論を先に書きます。
-
React.FC
ではpropsに暗黙的にchildrenが含まれ、React.VFC
ではchildrenが含まれない - 暗黙的にchildrenが含まれることでコンポーネントを外から見たときにchildrenを渡す必要があるかどうかの判断がつかない
-
@types/react
の18以降ではReact.FC
にchildrenが含まれない(現在のVFCの)ようになるのでその期間はVFCをVFCを使用する方が安全である
FCとVFC型定義の比較
型定義をしているファイルがあったので比較してみます。
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;
}
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;
}
FCの方はpropsの部分でPropsWithChildren
が含まれていることが分かります。
これによって暗黙的にpropsにchildrenが含まれていることになります。
まとめ
FCは暗黙的にPropsにchildrenが含まれているので、他者が読む際にわかりやすいVFCで明示的に宣言してあげましょうということでした。
v18からはFCにもchildrenが含まれなくなる & VFCが非推奨になるようなので(一次情報が見つからなかった)VFCを設定した場合は再度FCに直す対応も発生しそうです。
ちょっとしたモヤモヤが解決してスッキリしました!
--余談--
ちなみに今回このテーマを調べていて、DefinitelyTyped
というのが@types/react
とかのTypescriptの型定義を集めたリポジトリのことだっていうのは初めて知りました。
v18から含まれなくなるよっていうものをいろんなブログや記事で見たんですけどその情報ってどこに書かれてるんでしょう?
見つけた。
参考記事
2022/05/24追記
React v18がリリースされましたね!
型定義ファイルを見るとわかるようにReact.VFC
がdeprecatedになりました。
なのでこれからは安心してReact.FC
を使いましょう!