7: Todoの完了状態の更新
このステップで学ぶこと
Section titled “このステップで学ぶこと”前回はTodoの追加機能を作成しました。
今回はTodoの完了状態を更新する機能を作っていきましょう。
-
状態の更新
- 配列の要素の更新
- オブジェクトのプロパティの更新
-
条件付きレンダリング
- Todoの完了状態に応じたスタイルの切り替え
Todoの完了状態更新機能の作成
Section titled “Todoの完了状態更新機能の作成”src/app/todos/page.js
を以下の内容に更新します。
'use client';import style from './page.module.css';import { useState } from 'react';
export default function Todos() { const [todos, setTodos] = useState([ { id: 1, title: '買い物に行く', completed: false }, { id: 2, title: 'メールを確認する', completed: false }, { id: 3, title: '資料を作成する', completed: false }, { id: 4, title: '友達に電話する', completed: false }, { id: 5, title: '部屋の掃除', completed: false }, ]);
// 入力値の状態管理 const [newTodo, setNewTodo] = useState('');
// Todo追加処理 const handleSubmit = (e) => { e.preventDefault(); if (newTodo.trim() === '') return;
const newId = todos.length > 0 ? Math.max(...todos.map(t => t.id)) + 1 : 1; setTodos([...todos, { id: newId, title: newTodo, completed: false }]); setNewTodo(''); };
// 1. Todoの完了状態を更新する処理 const handleToggleComplete = (todoId) => { setTodos(todos.map(todo => todo.id === todoId ? { ...todo, completed: !todo.completed } : todo )); };
return ( <section className={style.container}> <h1>Todoリスト</h1>
{/* Todo追加フォーム */} <form onSubmit={handleSubmit} className={style.form}> <input type="text" value={newTodo} onChange={(e) => setNewTodo(e.target.value)} placeholder="新しいTodoを入力" className={style.input} /> <button type="submit" className={style.button}>追加</button> </form>
{/* Todo一覧 */} <div className={style.checkbox}> {todos.map(todo => ( <div key={todo.id}> {/* 2. Todoの完了状態に応じたスタイルの切り替え*/} <label className={todo.completed ? style.completed : ''}> <input type="checkbox" onChange={() => // 3. チェックボックスがクリックされたときの処理の登録 handleToggleComplete(todo.id)} /> {todo.title} </label> </div> ))} </div> </section> );}
コードの説明
Section titled “コードの説明”-
Todoの完了状態を更新する処理
const handleToggleComplete = (todoId) => {setTodos(todos.map(todo =>todo.id === todoId? { ...todo, completed: !todo.completed }: todo));};todoId
: 更新対象のTodoのIDを受け取りますtodos.map()
: 配列の各要素に対して処理を行いますtodo.id === todoId
: 更新対象のTodoを見つけます{ ...todo, completed: !todo.completed }
: Todoの完了状態を反転させますsetTodos()
: 更新されたTodo一覧を保存します
-
Todoの完了状態に応じたスタイルの切り替え
<label className={todo.completed ? style.completed : ''}>- 三項演算子を使用して、Todoの完了状態に応じてクラス名を動的に切り替えます
todo.completed
がtrue
の場合はstyle.completed
クラスを適用false
の場合は空文字列(デフォルトスタイル)を適用
-
チェックボックスがクリックされたときの処理の登録
<inputtype="checkbox"onChange={() => handleToggleComplete(todo.id)}/>onChange
イベントハンドラを使用して、チェックボックスの状態変更を検知- クリック時に
handleToggleComplete
関数を呼び出し、該当するTodoのIDを渡す - これにより、チェックボックスの状態に応じてTodoの完了状態が更新される
スタイルの更新
Section titled “スタイルの更新”src/app/todos/page.module.css
に以下のスタイルを追加します。
/* 省略 */
.button:hover { background-color: #0051a2;}
.completed { text-decoration: line-through; color: #888;}
🚀 動作確認
Section titled “🚀 動作確認”正しく動作しているか確認しましょう。
- チェックボックスをクリックするとTodoの完了状態が切り替わる
- 完了したTodoの見た目が変わる
よくある問題と解決方法
Section titled “よくある問題と解決方法”クリックしても見た目が変わらない
- イベントハンドラが設定されているか確認する
- イベントハンドラに書かれている内容に間違いがないか確認する
🎯 理解度チェック
Section titled “🎯 理解度チェック”以下の質問に答えて、学習内容を確認しましょう!
-
配列の各要素に処理を適用するときに使う関数は?
- A:
forEach()
- B:
map()
- C:
filter()
- D:
reduce()
- A:
答えを見る
答え: B: map()
map()
は配列の各要素に対して処理を行い、新しい配列を作成します- このステップでは特定のTodoの完了状態を更新するために使いました
-
オブジェクトのプロパティを展開して新しいオブジェクトを作るときに使う演算子は?
- A:
+
- B:
...
- C:
&&
- D:
||
- A:
答えを見る
答え: B: ...
- スプレッド演算子(
...
)は、オブジェクトのプロパティを展開して新しいオブジェクトを作成します - このステップでは、Todoオブジェクトのプロパティを更新するために使いました
このステップでは以下について学びました。
-
状態の更新
- 配列要素の更新
- オブジェクトのプロパティの更新
- スプレッド演算子
-
イベントハンドリング
- チェックボックスの状態変更イベント
-
条件付きレンダリング
- Todoの完了状態に応じたスタイルの切り替え