こんにちは!フロントエンドの最前線で、日々コードと格闘しているエンジニアです。
Reactを触り始めると、必ずと言っていいほどぶつかる壁があります。それが「Props(プロップス)に何を渡せばいいの?」という問題です。特に `React.ReactNode` とか `React.ReactElement` という型が出てきた瞬間、「なんか難しそう…」とブラウザを閉じそうになった経験、ありませんか?
大丈夫です。これ、実は「お弁当箱」と「中身」の関係で考えると、驚くほどスッキリ理解できるんです。今日はその謎を、一緒に紐解いていきましょう!
—
1. まずはイメージ:お弁当箱と中身
Reactのコンポーネントを「お弁当箱」だと想像してみてください。
`children` というのは、そのお弁当箱の中に詰める「おかず」たちです。
- React.ReactNode: 「お弁当箱に入れられるものすべて」。
- おにぎり(文字列)も、唐揚げ(コンポーネント)も、あるいは「何にも入れないよ(null)」という空っぽの状態も、全部OK。一番寛大な型です。
- React.ReactElement: 「お弁当箱に入れられる『完成したおかず』」。
- こちらは少し厳格です。`
` や `
` のように、Reactが「これはJSXの形をしているね」と認識できるものだけを指します。文字列や数字は含まれません。 2. なぜ使い分ける必要があるの?
「とりあえず `React.ReactNode` を使っておけばエラーにならないし、万能じゃない?」と思うかもしれません。確かにその通りです!
でも、プロの現場では「このコンポーネントには、特定の部品以外は入れたくない!」という状況がよくあります。
例えば、「カードコンポーネントには、専用の『タイトル部品』しか受け入れたくない」というようなルールを作りたい時です。何でもかんでも入る状態にしておくと、バグの温床になりかねませんよね。
3. 型を指定してみよう!
実際にコードで見てみましょう。まずは一番よく使う `React.ReactNode` と、少しこだわりたい時の `React.ReactElement` の違いです。
import React from ‘react’;
// ① React.ReactNodeの例:何でも来い!な寛大な箱
type BoxProps = {
children: React.ReactNode; // 文字列も数字もJSXも全部OK
};export const FlexibleBox = ({ children }: BoxProps) => {
return{children};
};// ② React.ReactElementの例:特定のコンポーネントだけを受け入れたい!
type CardProps = {
// ここには必ずReactの要素(や )だけが来る!
children: React.ReactElement;
};export const StrictCard = ({ children }: CardProps) => {
return{children};
};特定のコンポーネントだけを許可する方法
もし「このコンポーネントには `Button` コンポーネントしか許可したくない!」という場合は、`React.ReactElement` を使ってさらに厳しく制限できます。
// あえて型を絞り込むことで、ミスを未然に防ぐプロの技
type ButtonOnlyProps = {
children: React.ReactElement;
};const StrictButtonCard = ({ children }: ButtonOnlyProps) => {
return{children};
};—
4. つまずきやすいポイント:文字列を渡すとエラー?
ここで初心者の人が一番ひっかかるのがこれです。
`StrictCard`(`React.ReactElement`を指定したもの)に対して、うっかり普通の文字列を渡すと…エディタが赤く怒り出します。
// これはエラー!
//こんにちは!
// なぜなら、「こんにちは!」はReactElement(JSXのカタマリ)ではなく、ただの文字列だからです。「あれ?さっきまで動いてたのに!」と焦るかもしれませんが、これは「あなたが書いたコンポーネントのルールを、TypeScriptが守ってくれている」という証拠なんです。守られていることに感謝しつつ、`
こんにちは!` のようにJSXの形に包んであげれば、解決ですよ。
—
最後に:完璧を目指さなくて大丈夫
Reactの型定義は、最初は迷路のように感じるかもしれません。でも、一つだけ覚えておいてください。
「迷ったらまずは `React.ReactNode` を使っておけばいい」
これが現場のリアルな答えです。そこから「もう少し厳格にしたいな」「型でミスを防ぎたいな」と思った時に、初めて `React.ReactElement` という選択肢を取り出せばいいのです。
焦らず、一つずつ「お弁当箱」の中身を整理していくような感覚で、Reactのコードを楽しんで書いてみてくださいね。あなたのコードが、今日も誰かの役に立つことを願っています!
また何か詰まったら、いつでも聞きに来てくださいね。応援しています!

コメント