Reactの強みのひとつは「部品化(コンポーネント化)」が自然にできること。
そしてその部品にデータを渡す仕組みが「Props(プロップス)」。
今回のテーマはこの2つ:Propsの使い方と、部品化(コンポーネント分割)の考え方。
理由はシンプル:
例えるなら、「Reactはレゴブロック」。
小さな部品を組み合わせて、柔軟でメンテしやすいUIを作っていく。
Propsは「親コンポーネントから子コンポーネントに渡すデータや関数」のこと。
tsx
<TodoItem title="牛乳を買う" onDelete={handleDelete} />
この書き方で、TodoItem
という部品に、title
(文字列)とonDelete
(関数)を渡してる。
受け取る側(TodoItem.tsx
)はこう:
tsx
interface TodoItemProps {
title: string;
onDelete: () => void;
}
const TodoItem = ({ title, onDelete }: TodoItemProps) => {
return (
<div>
<span>{title}</span>
<button onClick={onDelete}>削除</button>
</div>
);
};
ポイント:
interface
でpropsの型を定義(TypeScriptの恩恵){}
でpropsを分割して受け取る(分かりやすく書ける)React初心者がよくやりがちなのが「全部App.tsx
に書く」パターン。
最初はそれでもいいけど、すぐに見通しが悪くなる。
理想:1コンポーネント = 1責務
今回のTodoアプリなら、こういう分割になる:
App.tsx → 状態管理 & 全体構成
TodoList.tsx → リスト表示担当
TodoItem.tsx → 1つのアイテムの見た目と削除ボタン
この分割をすることで:
子コンポーネント内で「何かアクションが起きたとき」に、親に伝えるには関数を渡す。
tsx
<TodoItem title="メモ" onDelete={() => onDelete(index)} />
親から子へ渡して、子がその関数を実行すると、親の状態が変わる。
このパターン、Reactで非常によく出てくる。
TypeScriptを使っているなら、propsに型をつけよう。
読みやすく、間違いにくく、補完も効く。
tsx
interface TodoListProps {
todos: string[];
onDelete: (index: number) => void;
}
propsの数が増えても、interface
で一括管理できるから便利。
TodoItem
, TodoList
など、見た目ごとに分割してみる👇 サンプルアプリ:Todoアプリ(Propsと分割)
interface
でpropsの型定義をしよう