やあ。Reactの海を渡り歩いている諸君、今日もコンポーネントの再利用性に頭を悩ませているかな?
「Hooksがある今、Render Propsなんて過去の遺物じゃないのか?」という声が聞こえてきそうだが、それは大きな誤解だ。確かにロジックの共有はカスタムフックが主役になった。しかし、「UIの描画レイヤーを外部から注入し、コンポーネントの責務を分離する」という点において、Render Propsは依然として最強のツールの一つだ。
今日は、実務で「あ、ここでRender Props使えば綺麗に書けるな」と即座に判断できるよう、その本質とTypeScriptによる型定義の流儀を叩き込むぞ。
—
1. Render Propsは「UIの穴あけ」である
Render Propsの仕組みは単純だ。コンポーネントの `children` や独自のプロパティに、JSXを返す「関数」を渡すだけ。
ブラウザの裏側で何が起きているか? Reactは、その関数が返すJSXを、親コンポーネントが管理しているステートやロジックと組み合わせて評価する。つまり、「データやロジックを持つ主体」と「見た目を描画する主体」を強制的に分離する設計手法なんだ。
これがなぜ重要かというと、例えば「マウス追従」や「フォームのバリデーション」のような、状態管理は複雑だが見た目は多様なコンポーネントを作る際、Render Propsを使えば、見た目の実装を親側(利用側)に完全に委譲できるからだ。
2. TypeScriptで型安全に実装する:実務の作法
中級者なら、ここを曖昧にしてはいけない。型定義が不完全なRender Propsは、チーム開発においてただの「爆弾」だ。
以下は、`data`をフェッチして、その結果に応じてUIを描画するコンポーネントの例だ。
import React, { useState, useEffect } from ‘react’;
// Render Propsの関数の引数の型を定義する
interface RenderProps
data: T | null;
loading: boolean;
error: Error | null;
}
// データ取得コンポーネントのプロパティ定義
interface DataFetcherProps
url: string;
// render関数を受け取るための型定義。React.ReactNodeを返すように制限する
children: (props: RenderProps
}
export const DataFetcher =
const [data, setData] = useState
const [loading, setLoading] = useState
const [error, setError] = useState
useEffect(() => {
fetch(url)
.then((res) => res.json())
.then((json) => setData(json))
.catch((err) => setError(err))
.finally(() => setLoading(false));
}, [url]);
// ここが心臓部。子コンポーネントに関数を渡して実行する
return <>{children({ data, loading, error })}>;
};
なぜこの型定義が必要なのか?
`
—
3. 現場での呼び出し方:クリーンなコードを書こう
さて、実際にこれを使う側を見てみよう。
interface User {
id: number;
name: string;
}
const UserProfile = () => {
return (
{({ data, loading, error }) => {
// ここでUIの出し分けを行う。責務が明確だ
if (loading) return
;
if (error) return
;
if (!data) return null;
return
{data.name}
;
}}
);
};
どうだい? 非常にスッキリしているだろう。
`DataFetcher`は「APIを叩く」というロジックだけに集中し、`UserProfile`は「どう表示するか」だけに集中している。
4. 最後に:設計の「引き出し」を増やす
Render PropsとHooks、どちらを使うべきか迷ったら、こう自問自答してほしい。
- そのロジックを複数のコンポーネントで使い回すだけか? → カスタムHooksで十分だ。
- 「見た目」も含めて、利用側が柔軟に構造を変えたいか? → Render Propsの出番だ。
特に、複雑なテーブルのセルレンダリングや、モーダルの動的なコンテンツ注入など、UIの構造そのものを外部から制御したい場合には、Render Propsは今でも最強の武器だ。
Reactの進化は速い。しかし、「コンポーネントをどう分割し、どう疎結合にするか」というアーキテクチャの根幹は変わらない。この「関数を渡す」というシンプルなパターンを使いこなせれば、君のコードはグッとプロフェッショナルなものになるはずだ。
次は、これをどうテストするか……の話をしたいところだが、それはまた別の機会にしよう。現場からは以上だ。健闘を祈る!

コメント