こんにちは!フロントエンドの現場で日々コードと格闘しているチーフアーキテクトです。
Reactを学び始めると、必ず一度は立ち止まるのが「Props(プロップス)」の型定義、その中でも特に `React.ReactNode` という謎の型ですよね。ネットで調べても「何でも入る型です」なんて書かれていて、結局「どれくらい何でもいいの?」と不安になったりしませんか?
大丈夫です。今日は、この「React界の万能包丁」のような型について、現場の知恵を交えながら噛み砕いてお話ししますね。
—
React.ReactNodeって、結局なんなの?
例え話をしましょう。あなたが「お弁当箱」を作っていると想像してください。
このお弁当箱(コンポーネント)には、何を入れても自由です。
- おにぎり(テキスト)
- 唐揚げ(ボタンやアイコン)
- さらにおかずを入れるための小分けカップ(別のコンポーネント)
- 何にも入れない空っぽ(null)
この「お弁当箱の中身」として許可されているすべての食材を、Reactが一つにまとめた名前が `React.ReactNode` です。「これならお弁当に入れても安全だよ」というリストだと考えてください。
なぜ他の型じゃダメなの?
`string`(文字列)だけにすると、アイコンが入りません。`JSX.Element` にすると、ただの文字列や数字が怒られてしまいます。「Reactで画面に表示できるものなら何でも受け取りたい!」という時に、一番広くて優しいのがこの型なんです。
—
実際にコードで見てみよう
例えば、枠線で囲むだけのシンプルな「カード・コンポーネント」を作ってみます。
import React from ‘react’;
// 「枠」だけを用意するコンポーネント
// childrenという名前で中身を受け取ります
type CardProps = {
children: React.ReactNode;
};
export const Card = ({ children }: CardProps) => {
return (
{children}
);
};
この `Card` コンポーネントは、こんな風に何でも受け取れます。
// 使い方
const App = () => {
return (
タイトル
{/ タグもOK /}
ここには文章が入ります。
{/ 文章もOK /}
{/ ボタンもOK /}
);
};
—
現場で役立つ「使い分け」の極意
「じゃあ、全部 `React.ReactNode` にすればいいの?」と言われると、実はそうではありません。ここがチーフアーキテクトとしてのこだわりポイントです。
1. なぜ「何でもOK」だと困るのか?
お弁当箱に「何でも入れていいよ」と言いすぎると、たまに「お弁当箱の中に、さらにお弁当箱を100個入れる」というような、設計上の無茶をする人が出てきます(笑)。
2. 使い分けの基準
- レイアウト部品(カード、モーダル、ボタンの中身など):
ここには `React.ReactNode` を使いましょう。「中身に何が来るかわからない」という柔軟性が一番の武器だからです。
- 特定の役割がある場合:
もし「絶対に文章しか入れてほしくない」なら、迷わず `string` を使ってください。型を厳しく縛ることは、未来の自分やチームへの「ここには文字しか入れないでね」という親切なメッセージになります。
—
まとめ:怖がらなくて大丈夫!
`React.ReactNode` は、いわば「Reactが画面にレンダリングできるものなら、なんでもカモン!」という懐の深い型です。
初心者のうちは、とりあえず「中身を自由に差し替えたいコンポーネント」を作るときは、`children: React.ReactNode` と書いておけば間違いありません。Reactが「お、お弁当箱ですね、了解しました!」としっかり受け止めてくれます。
コードを書くとき、型は「縛り付けるための鎖」ではなく、「事故を防ぐためのガードレール」です。まずはこの便利な型を使って、自由にコンポーネントを作ってみてくださいね。
また何か迷ったら、いつでも聞きに来てください。あなたのエンジニアライフを応援しています!

コメント