ReactでPropsとStateを組み合わせてTodoアプリを作ろう!初心者でもできるReact入門
生徒
「ReactでPropsとStateの違いはわかったんですけど、実際にどうやって一緒に使うんですか?」
先生
「良い質問ですね。Propsは親から子に渡すデータ、Stateはそのコンポーネント自身が持つデータでしたね。これを組み合わせると、実用的なアプリが作れるんですよ。」
生徒
「例えばどんなアプリですか?」
先生
「初心者におすすめなのがTodoアプリです。やることリストを追加したり削除したりできるアプリです。PropsとStateの両方を使う練習にぴったりですよ!」
1. Todoアプリとは?
Todoアプリとは、やることリストを管理するシンプルなアプリです。「買い物する」「宿題をやる」「メールを送る」といったタスクをリストに追加し、終わったら削除する仕組みです。初心者がプログラミングを学ぶときの定番練習として有名です。
Reactでは、このTodoアプリを作ることでPropsとStateを組み合わせて使う方法を自然に学べます。Stateでタスクを管理し、Propsを通じて子コンポーネントに渡すことで、画面を効率よく更新できます。
2. Stateでタスクを管理する
まず、やることリスト(Todoリスト)は、アプリ全体で管理したいデータです。このような変化するデータはuseStateを使ってStateとして保存します。
たとえばconst [todos, setTodos] = useState([])と書くと、空のリストをStateとして持てます。setTodosを呼び出すことで新しいタスクを追加できます。
3. Propsで子コンポーネントにデータを渡す
Todoアプリでは「タスク入力フォーム」「タスク一覧表示」「タスク削除ボタン」など複数の部品が必要です。これを別々のコンポーネントに分けることで、コードが整理されて見やすくなります。
ただし、子コンポーネントは自分でタスク一覧を管理できません。そこで親コンポーネント(App)が持つtodosを、Propsとして子コンポーネントに渡します。
これによって、子コンポーネントはPropsを通じてタスク一覧を受け取り、表示や削除処理ができるようになります。
4. PropsとStateを組み合わせたTodoアプリの実装例
ここでは実際に、入力したタスクをリストに追加し、削除もできるTodoアプリを作ってみましょう。
import React, { useState } from "react";
function TodoItem({ todo, onDelete }) {
return (
<li>
{todo}
<button onClick={onDelete}>削除</button>
</li>
);
}
function TodoList({ todos, onDelete }) {
return (
<ul>
{todos.map((todo, index) => (
<TodoItem key={index} todo={todo} onDelete={() => onDelete(index)} />
))}
</ul>
);
}
function App() {
const [todos, setTodos] = useState([]);
const [input, setInput] = useState("");
const addTodo = () => {
if (input.trim() === "") return;
setTodos([...todos, input]);
setInput("");
};
const deleteTodo = (index) => {
const newTodos = todos.filter((_, i) => i !== index);
setTodos(newTodos);
};
return (
<div>
<h1>Todoアプリ</h1>
<input
type="text"
value={input}
onChange={(e) => setInput(e.target.value)}
placeholder="タスクを入力"
/>
<button onClick={addTodo}>追加</button>
<TodoList todos={todos} onDelete={deleteTodo} />
</div>
);
}
export default App;
5. PropsとStateの役割を整理しよう
このTodoアプリでは、次のように役割を分担しています。
- State(Appコンポーネント):タスク一覧(todos)と入力値(input)を管理
- Props(子コンポーネントへ渡す):TodoListにタスク一覧と削除関数を渡す
- Props(さらに子へ渡す):TodoItemに個別のタスクと削除関数を渡す
このように、Stateはデータを保持する役割、Propsはそのデータや処理を子に渡す役割を担っています。両方を使うことで、アプリ全体がきちんと連携し、変更がすぐに画面に反映されます。
6. 初心者が理解しておきたいポイント
PropsとStateを組み合わせると便利ですが、最初は混乱しやすいです。以下の点を意識すると理解が深まります。
- Stateは「このコンポーネントが自分で持つデータ」
- Propsは「親から子に渡されるデータ」
- Propsは読み取り専用で変更できない(変更は親で行い、子はイベントを通じて伝える)
これを理解できれば、Todoアプリのような実用的なアプリを作れるようになります。
まとめ
この記事では、ReactでPropsとStateを組み合わせたTodoアプリの作り方を解説しました。Propsは親コンポーネントから子コンポーネントへデータや関数を渡すための仕組みであり、Stateはコンポーネント自身が管理する変更可能なデータです。Todoアプリの例では、Stateでタスク一覧と入力値を管理し、Propsを通じて子コンポーネントに渡すことで、画面の表示やタスク削除がリアルタイムで反映されます。これにより、Reactアプリ全体のデータの流れを整理し、可読性や保守性を高めることができます。
具体的には、AppコンポーネントでuseStateを使ってタスク一覧(todos)と入力値(input)を管理し、TodoListにtodosと削除関数をPropsとして渡します。さらにTodoItemに個別のタスクと削除関数をPropsとして渡すことで、子コンポーネントがそれぞれのタスクを表示し、削除操作を実現しています。PropsとStateを適切に組み合わせることで、データの一方向の流れを保ちつつ、効率的にUIを更新できるのがReactの強みです。
初心者にとっては、StateとPropsの違いや役割を理解することが重要です。Stateは「コンポーネント自身が持つデータ」、Propsは「親から子に渡されるデータ」であることを押さえておきましょう。Propsは読み取り専用で直接変更できません。子コンポーネントからデータを変更したい場合は、イベントを通じて親に伝え、親がStateを更新することで画面に反映されます。
import React, { useState } from "react";
function TodoItem({ todo, onDelete }) {
return (
<li>
{todo}
<button onClick={onDelete}>削除</button>
</li>
);
}
function TodoList({ todos, onDelete }) {
return (
<ul>
{todos.map((todo, index) => (
<TodoItem key={index} todo={todo} onDelete={() => onDelete(index)} />
))}
</ul>
);
}
function App() {
const [todos, setTodos] = useState([]);
const [input, setInput] = useState("");
const addTodo = () => {
if (input.trim() === "") return;
setTodos([...todos, input]);
setInput("");
};
const deleteTodo = (index) => {
setTodos(todos.filter((_, i) => i !== index));
};
return (
<div>
<h1>Todoアプリ</h1>
<input
type="text"
value={input}
onChange={(e) => setInput(e.target.value)}
placeholder="タスクを入力"
/>
<button onClick={addTodo}>追加</button>
<TodoList todos={todos} onDelete={deleteTodo} />
</div>
);
}
export default App;
生徒
「PropsとStateを組み合わせることで、入力したタスクを追加したり削除したりできることがわかりました。」
先生
「そうですね。Stateはコンポーネント自身が管理するデータ、Propsは親から子へ渡すデータや関数、という役割を理解できれば、アプリ全体のデータフローを整理して構築できます。」
生徒
「子コンポーネントはPropsを受け取るだけで、直接変更できないんですね。」
先生
「その通りです。変更は親コンポーネントのStateを更新することで行い、画面に反映されます。これがReactの一方向データフローの基本です。」
生徒
「今回のTodoアプリでPropsとStateを同時に扱う方法が理解できたので、次はもっと複雑なアプリにも挑戦できそうです。」
先生
「その意気です。PropsとStateを正しく理解すれば、Reactで効率的にUIを更新できるアプリを作れるようになります。」