ReactでTodoアプリを作っているのだが、stateで管理しているタスクを更新し、更新後のstateをセッションストレージに保存しようとすると、何故か更新前のstateが保存されている。
つまり、更新したはずのstateが反映されていないのだ。
この問題についての解決法を本記事ではまとめていく。
元のコード
stateはuseState
で管理し、以下のフォームからタスクを追加する。

01 02 03 04 05 06 07 08 09 10 11 12 13 14 | const [tasks, setTasks] = useState([]); // タスクの追加 const createTask = (e) => { e.preventDefault(); const { taskName } = e.target.elements; setTasks([{ name: taskName.value, date: dateFormat( new Date()), }, ...tasks]); saveToSessionStorage(tasks); } |
8行目のsetTasks
で既存のタスクに新規タスクを追加し、13行目の関数呼び出しでセッションストレージにtasks
を保存している。
一見これでうまくいくように見えるが、実はuseState
で管理されるstateは、関数呼び出し後にしか更新されないのだ。
つまり、createTask
関数内では更新後のtasks
を参照することは出来ないということ。
一時変数に更新後のstateを保存する
この問題を解決するには、更新後のstateをいったん一時変数に保存させておく必要がある。
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 | const [tasks, setTasks] = useState([]); // タスクの追加 const createTask = (e) => { e.preventDefault(); const { taskName } = e.target.elements; // 更新後のstateを一時的に保存 const tmpTasks = [{ name: taskName.value, date: dateFormat( new Date()), }, ...tasks]; setTasks(tmpTasks); saveToSessionStorage(tmpTasks); } |
元コードを修正したものがこちら。
9行目、tmpTasks
に更新後のstateを一時的に保存し、これをsetTasks
、saveToSessionStorage
でそれぞれ利用している。
一手間必要になるが、これで更新後のstateを扱うことができるようになる。