From 33bf23aac4af3d9741558dca027ef09cc8440c3c Mon Sep 17 00:00:00 2001 From: KentaroKumode <23e1273@andrew.ac.jp> Date: Sun, 13 Jul 2025 20:12:08 +0900 Subject: [PATCH] =?UTF-8?q?=E3=82=B3=E3=83=A1=E3=83=B3=E3=83=88=E3=82=A2?= =?UTF-8?q?=E3=82=A6=E3=83=88=E3=82=92=E3=82=88=E3=82=8A=E5=85=B7=E4=BD=93?= =?UTF-8?q?=E7=9A=84=E3=81=AB=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/page.tsx | 95 ++++++++++++++++++++++++++---------------------- 1 file changed, 52 insertions(+), 43 deletions(-) diff --git a/src/app/page.tsx b/src/app/page.tsx index 3f633fb..b85b938 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,81 +1,90 @@ -'use client'; // ← これはNext.jsのApp Routerで、クライアントコンポーネントとして実行させる指示。useStateなどクライアント専用フックを使うために必須。 +'use client'; -import { useState } from 'react'; // Reactの"状態管理用"のフック。状態が変化したら再レンダリングが起きる。 +import { useState } from 'react'; -// Todo型の定義。オブジェクトが必ずid, text, completedというプロパティを持つことを保証。 +// Todo型の定義 type Todo = { - id: number; // ユニークな識別子。今回はDate.now()で一意性をある程度確保。 - text: string; // TODOの内容。ユーザーが入力する文字列。 - completed: boolean; // 完了したかどうかのフラグ。チェックボックスに対応。 + id: number; + text: string; + completed: boolean; }; -export default function Home() { // Reactコンポーネント。Next.jsのデフォルトエクスポートとしてトップページに描画される。 - // 状態変数定義。todosはTodoの配列、inputValueは入力中のテキスト。 - const [todos, setTodos] = useState([]); // Todoリスト本体。初期値は空配列。 - const [inputValue, setInputValue] = useState(''); // 入力欄の中身。初期値は空文字。 - const [showConfirm, setShowConfirm] = useState(false); // 削除確認ダイアログを表示するかどうか。 - const [targetId, setTargetId] = useState(null); // 確認ダイアログで削除対象のTodoのIDを一時保持。 - const [showInputAlert, setShowInputAlert] = useState(false); // 空欄入力時の警告ダイアログ +export default function Home() { + // Todoリスト本体の状態管理 + const [todos, setTodos] = useState([]); // Todo配列を保持 + + // 入力欄の状態管理 + const [inputValue, setInputValue] = useState(''); // 入力中のテキスト + + // 削除確認ダイアログの表示状態 + const [showConfirm, setShowConfirm] = useState(false); // ダイアログ表示フラグ + + // 削除対象のTodoのID + const [targetId, setTargetId] = useState(null); // 削除対象ID + + // 空欄入力時の警告ダイアログ表示状態 + const [showInputAlert, setShowInputAlert] = useState(false); // 空欄警告フラグ // 新しいTODOを追加する関数 const addTodo = () => { - if (inputValue.trim() === '') { // 入力が空欄だったら処理を中止。trim()で空白も除去。 - setShowInputAlert(true); // カスタムダイアログ表示 + // 入力が空欄だったら警告ダイアログ表示 + if (inputValue.trim() === '') { + setShowInputAlert(true); // 警告ダイアログを表示 return; } + // 新しいTodoオブジェクトを作成 const newTodo: Todo = { - id: Date.now(), - text: inputValue, - completed: false + id: Date.now(), // 一意なID + text: inputValue, // 入力値 + completed: false // 初期状態は未完了 }; - setTodos([...todos, newTodo]); - setInputValue(''); + setTodos([...todos, newTodo]); // Todoリストに追加 + setInputValue(''); // 入力欄をクリア }; - // フォームが送信されたときの処理 + // フォーム送信時の処理 const handleSubmit = (e: React.FormEvent) => { - e.preventDefault(); // ページ全体のリロードを防ぐ。SPA的挙動にする。 - addTodo(); // addTodo関数を実行。 + e.preventDefault(); // ページリロード防止 + addTodo(); // Todo追加処理 }; - // Todoの完了状態をトグル(反転)する関数 + // Todoの完了状態をトグルする関数 const toggleTodo = (id: number) => { const updatedTodos = todos.map(todo => { if (todo.id === id) { - return { ...todo, completed: !todo.completed }; // 対象のcompletedだけ反転。 + return { ...todo, completed: !todo.completed }; } - return todo; // それ以外はそのまま。 + return todo; }); - setTodos(updatedTodos); // 新しい配列をset。Reactはこれを検知して再描画する。 + setTodos(updatedTodos); // 状態更新 }; - // 削除ボタンが押されたときの仮処理。確認ダイアログを表示。 + // 削除ボタンが押されたときの処理(確認ダイアログ表示) const handleDeleteClick = (id: number) => { - setShowConfirm(true); // ダイアログ表示 - setTargetId(id); // 対象ID記憶 + setShowConfirm(true); // 削除確認ダイアログ表示 + setTargetId(id); // 削除対象IDをセット }; // ダイアログで「はい」が押されたときの本削除処理 const confirmDelete = () => { - if (targetId !== null) { // nullチェックを忘れずに + if (targetId !== null) { // 削除対象IDがセットされているか確認 setTodos(todos.filter(todo => todo.id !== targetId)); // 該当ID以外を残す setShowConfirm(false); // ダイアログを閉じる - setTargetId(null); // 状態を初期化 + setTargetId(null); // 削除対象IDをリセット } }; // ダイアログで「いいえ」が押されたときの処理 const cancelDelete = () => { - setShowConfirm(false); - setTargetId(null); + setShowConfirm(false); // ダイアログを閉じる + setTargetId(null); // 削除対象IDをリセット }; // 空欄入力時ダイアログを閉じる関数 const closeInputAlert = () => { - setShowInputAlert(false); + setShowInputAlert(false); // 警告ダイアログを閉じる }; - // JSX: 実際に表示されるUI定義 return (
{/* 全体の背景や余白 */} @@ -86,8 +95,8 @@ export default function Home() { // Reactコンポーネント。Next.jsのデ
setInputValue(e.target.value)} // 入力をリアルタイムに反映 + value={inputValue} // 入力欄の値を状態と連動 + onChange={(e) => setInputValue(e.target.value)} // 入力値変更時に状態更新 placeholder="TODOを入力してEnterキー" className="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" /> @@ -106,14 +115,14 @@ export default function Home() { // Reactコンポーネント。Next.jsのデ toggleTodo(todo.id)} // トグル動作 + onChange={() => toggleTodo(todo.id)} // チェックボックス変更時に完了状態をトグル className="mr-3 h-5 w-5 cursor-pointer" /> {todo.text} - + {/* 削除確定 */} + {/* 削除キャンセル */} )} @@ -139,7 +148,7 @@ export default function Home() { // Reactコンポーネント。Next.jsのデ

TODOを入力してください