実施条件
[React][L2] テキストボックスの内容を保持するを理解していること
環境
MacBook Pro (2.3 GHz 8コアIntel Core i9)
macOS 14.0(23A344)
Homebrew 4.3.8
gh 2.52.0
ソースコードの前に
フォルダ構成
folda_structure
├── package.json
├── public/
│ └── index.html
├── src/
│ ├── index.jsx
│ ├── Todo.jsx
│ └── styles.css
│
index.html
index.html
<!DOCTYPE html>
<html lang="en">
<head> </head>
<body>
<div id="root"></div>
</body>
</html>
index.jsx
index.jsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { Todo } from "./Todo";
const rootElement = document.getElementById("root");
const root = createRoot(rootElement);
root.render(
<StrictMode>
<Todo />
</StrictMode>
);
ソースコード
Todo.jsx(旧)
Todo.jsx
import { useState } from "react";
import "./styles.css";
export const Todo = () => {
const [todoText, setTodoText] = useState("");
const [incompleteTodos, setIncompleteTodos] = useState([
"TODOです1",
"TODOです2",
]);
const [completeTodos, setCompleteTodos] = useState([
"TODOでした1",
"TODOでした2",
]);
const onChangeTodoText = (event) => setTodoText(event.target.value);
return (
<>
<div className="input-area">
<input placeholder="TODOを入力"></input>
<input placeholder="TODOを入力" value={todoText} onChange={onChangeTodoText}></input>
<button>追加</button>
</div>
<div className="incomplete-area">
<p className="title">未完了のTODO</p>
<ul>
{incompleteTodos.map((todo) => {
return (
<li key={todo}>
<div className="list-row">
<p>{todo}</p>
<button>完了</button>
<button>削除</button>
</div>
</li>
);
})}
</ul>
</div>
<div className="complete-area">
<p className="title">完了のTODO</p>
<ul>
{completeTodos.map((todo) => {
return (
<li>
<div className="list-row">
<p>{todo}</p>
<button>戻す</button>
</div>
</li>
);
})}
</ul>
</div>
</>
);
};
Todo.jsx
Todo.jsx
import { useState } from "react";
import "./styles.css";
export const Todo = () => {
const [todoText, setTodoText] = useState("");
const [incompleteTodos, setIncompleteTodos] = useState([
"TODOです1",
"TODOです2",
]);
const [completeTodos, setCompleteTodos] = useState([
"TODOでした1",
"TODOでした2",
]);
const onChangeTodoText = (event) => setTodoText(event.target.value);
+ const onClickAdd = () => {
+ if (todoText === "") {
+ return;
+ } else {
+ const newTodos = [...incompleteTodos, todoText];
+ setIncompleteTodos(newTodos);
+ setTodoText("");
+ }
+ };
return (
<>
<div className="input-area">
<input placeholder="TODOを入力"></input>
<input placeholder="TODOを入力" value={todoText} onChange={onChangeTodoText}></input>
- <button>追加</button>
+ <button onClick={onClickAdd}>追加</button>
</div>
<div className="incomplete-area">
<p className="title">未完了のTODO</p>
<ul>
{incompleteTodos.map((todo) => {
return (
<li key={todo}>
<div className="list-row">
<p>{todo}</p>
<button>完了</button>
<button>削除</button>
</div>
</li>
);
})}
</ul>
</div>
<div className="complete-area">
<p className="title">完了のTODO</p>
<ul>
{completeTodos.map((todo) => {
return (
<li>
<div className="list-row">
<p>{todo}</p>
<button>戻す</button>
</div>
</li>
);
})}
</ul>
</div>
</>
);
};
解説
目的
-
button
タグ(追加)を押下した時に、最新のtodoText
を、配列incompleteTodos
に追加する
コーディング
-
button
タグ(追加)を押下した際に発火する、onClick
イベントを設定するTodo.jsx- <button>追加</button> + <button onClick={onClickAdd}>追加</button>
-
onClick
イベントで呼び出される関数をonClickAdd
として設定するTodo.jsx+ const onClickAdd = () => { + };
-
onClickAdd
にて、スプレッド構文を用いて、最新のtodoText
の値を、配列incompleteTodos
に追加して、newTodos
として定義するTodo.jsxconst onClickAdd = () => { + const newTodos = [...incompleteTodos, todoText]; };
-
newTodos
を配列incompleteTodos
の更新関数であるsetIncompleteTodos
に引数として渡す
= 配列incompleteTodos
を更新するTodo.jsxconst onClickAdd = () => { const newTodos = [...incompleteTodos, todoText]; + setIncompleteTodos(newTodos); };
-
テキストボックスを""に戻す
Todo.jsxconst onClickAdd = () => { const newTodos = [...incompleteTodos, todoText]; setIncompleteTodos(newTodos); + setTodoText(""); };
-
値を入力していなくても、空文字で追加ができてしまうため、
if
で条件分岐するTodo.jsxconst onClickAdd = () => { + if (todoText === "") { + return; + } else { const newTodos = [...incompleteTodos, todoText]; setIncompleteTodos(newTodos); setTodoText(""); + } };
処理
-
button
タグ(追加)を押下した際に、onClickAdd
が起動する -
todoText
に保持された値が、配列incompleteTodos
に追加され、newTodos
に格納される -
newTodos
を引数として、setIncompleteTodos
で配列incompleteTodos
を更新する - 配列
incompleteTodos
をmap
メソッドで、レンダリングされる