Reactのstateについて教えていただきたいです。
stateがどのような動きをしているのか教えていただきたいです。
reactにて簡単なTodoアプリを作成しています。
その中で試行錯誤するうちに記述したコードがなぜその挙動をするか掴めなくなってしまい、
ご質問させていただきました。
オープンな質問になってしまい申し訳ありませんが、
アドバイスを頂戴できますと幸いです。
// import React from "react";
import React, { useState } from "react";
import { v4 as uuidv4 } from "uuid";
const App = () => {
const [todoText, setTodoText] = useState("");
const [addTodoList, setAddTodoList] = useState([]);
const handleChange = (e) => setTodoText(e.target.value);
const onClickAdd = () => {
if (todoText === "") return;
setAddTodoList([...addTodoList, { comment: todoText, status: "作業中" }]);
setTodoText("");
};
const [deleteTodoList, setDeleteTodoList] = useState([]);
const clickDeleteButton = (todo, index) => {
setDeleteTodoList(addTodoList.splice(index, 1));
console.log("addTodoList", addTodoList);
console.log("todo", todo);
console.log("index", index);
console.log(deleteTodoList);
};
const [completeTodos, setCompleteTodos] = useState([]);
const clickStatusButton = (todo, index) => {
if (todo.status === "作業中") {
setCompleteTodos(() => {
todo.status = "完了";
});
}
console.log("addTodoList", addTodoList);
console.log("completeTodos", completeTodos);
console.log(index, todo);
};
return (
<div>
<h1>TodoList</h1>
<input type="radio" />
すべて
<input type="radio" />
作業中
<input type="radio" />
完了
<table>
<thead>
<tr>
<td>ID</td>
<td>コメント</td>
<td>状態</td>
</tr>
</thead>
<tbody>
{addTodoList.map((todo, index) => (
<tr key={uuidv4()}>
<td>{`${index + 1}`}</td>
<td>{`${todo.comment}`}</td>
<td>
<button
onClick={() => clickStatusButton(todo, index)}
>{`${todo.status}`}</button>
</td>
<td>
<button onClick={() => clickDeleteButton(todo, index)}>
{/* addTodoListのtodoとindexを渡している */}
{/* イベントハンドラで引数がある場合()=>関数(引数)の記載が必要 */}
削除
</button>
</td>
</tr>
))}
</tbody>
</table>
<h2>新規タスクの追加</h2>
<input type="text" value={todoText} onChange={handleChange} />
<button onClick={() => onClickAdd()}>追加</button>
</div>
);
};
export default App;
タスクのstatusを変更する下記についてです。
const [completeTodos, setCompleteTodos] = useState([]);
const clickStatusButton = (todo, index) => {
if (todo.status === "作業中") {
setCompleteTodos(() => {
todo.status = "完了";
});
}
console.log("addTodoList", addTodoList);
console.log("completeTodos", completeTodos);
console.log(index, todo);
};
上記の挙動としては、
→タスクを複数入力
→一回目、「作業中」ボタンをクリックすると「完了」ボタンに変化
logを確認するとstatusも完了に「変化」している
→二回目、他のタスクの「作業中」ボタンをクリック、ボタンは「作業中」のまま。
logを確認するとタスクのstatusは「完了」に変化している。
また、setStateの認識として、下記をイメージしております。
const [completeTodos, setCompleteTodos] = useState([]);
[変数,変更するための関数]=初期値
setCompleteTodos(completeTodosをどうするか)
この通りに当てはめていくと、上記で記載したコードでは、
初期値空の配列、「completeTodos」のtodo.statusを完了にする、という事になるのかなと思いました。
また、statusを完了にして「completeTodos」の中に格納するのかともちらっと思いましたが、ログを確認するとそのうな形式は特にありませんでした。
正直よく分からないけど、「addTodoList」の中のtodo.statusは変更できる、一回目だけボタンの表示も変わる、、なぜこの挙動をするか分からなくなってしまいました。
そもそもsetStateの認識が間違っているのかなと思いましたが、決定的な理解につながらずご質問させていただきました。