Astroを利用して勤怠管理を作っていくための学習過程をアウトプット中。
これまでの記事はこちら。
データベース(として利用していたスプレッドシート)に保存することはできたけど、入力したTodoリストはやっぱりトップページにも表示させたいよなぁと思って次の学びのステップへと移行。
Astroはマルチフレームワーク対応なので、reactでコンポーネント作成もできるけど、Next.jsだったら切り分けなくても同じファイル内に記述することもできるようなぁと思い世の中の流れも鑑みてnext.jsでもやってみることに。
今回学びたかったのはuseHooksのこと
たくさんHooksはあるけど、とりあえず有名どころというか基本になってるようなuseStateを使ってみることにした。
コード全容
"use client";
import { useCallback, useState } from "react";
export default function Home() {
// 入力欄の管理
const [inputValue, setInputValue] = useState("");
// タスクのリスト管理
const [taskList, setTaskList] = useState<string[]>([]);
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setInputValue(e.target.value);
}
const addTasks = useCallback(() => {
setTaskList((items) => [...items, inputValue]);
setInputValue("");
}, [inputValue]);
return (
<div>
<input
type="text"
value={inputValue}
onChange={handleInputChange}
/>
<button onClick={addTasks}>タスクを追加</button>
<ul>
{taskList.map((item, key) => {
return <li key={key}>{item}</li>
})}
</ul>
</div>
);
}
という感じでローカルホストを立ち上げるとtodoリストの更新がトップページ上でできるようになって、リロードしたらリセットされるといったところに行き着いた。
でも、これを一目見ただけだと後から見返したらよくわからんなーというのが正直なところ。
なので、どんな手順で考えたかというのを記録しておこうと思う。
まず必要なのは、HTMLの入力部分
まずは入力してリストに追加できるようなinput
タグとbutton
タグを用意する。
この時、inputタグには属性値をいろいろ指定することができるわけだけど、デフォで入っているのはtype属性のみ。
inputタグに入力した文字列・数字を表示させたままにしたり、todoリストの配列に追加したりする目的でvalue属性に一つ変数を入れておく必要があって、入力値の管理をするために一つ目のuseStateが必要になる。
const [inputValue, setInputValue] = useState("");
<input
type="text"
value={inputValue}
/>
この時、初期値としては空欄にしておきたいので、useStateの引数に""を指定している。
次に必要となるのがinputタグの入力値を更新するためのonChange属性
現状のままだとvalue={inputValue}の指定で、初期値を空欄にしてるので、何を入力したとしても空欄のままになってしまう。
この状況を改善するために、入力値を受け取ってinputタグの中を更新しておくという処理が必要になる。
そのためにonChange属性には値を更新させる任意の関数を作る必要がある。
const handleInputChange = (e) => {
setInputValue(e.target.value);
}
<input
type="text"
value={inputValue}
onChange={handleInputChange}
/>
が追加されることになる。
次に作るのはbuttonタグの押下処理
ここで実装するのは
- ボタンタグをクリック
- タスクを配列に追加する任意の関数を実行させる
- タスクを配列に追加する関数が発火したらタスクリストを更新してHTML要素として出力
といったことになる。今回はそのためにaddTasks関数を用意した。タスクリストの管理、更新を目的として二つ目のuseStateが必要となる。
// タスクのリスト管理
const [taskList, setTaskList] = useState<string[]>([]);
const addTasks = useCallback(() => {
setTaskList((items) => [...items, inputValue]);
setInputValue("");
}, [inputValue]);
<button onClick={addTasks}>タスクを追加</button>
<ul>
{taskList.map((item, key) => {
return <li key={key}>{item}</li>
})}
</ul>
あとはHTML要素をフラグメントによって囲っておけばページが表示されるようになる。
まとめ
今回のように出来上がったものを見るだけではなく、どう考えてコードを上に書いたり下に書いたり、関数の中に入れたりコンポーネントとして切り分けたりといった手順がわかればもっと作りやすくなるなぁと感じた。
同じファイルの中で作れてしまうのでnext.jsは結構やりやすい。
あとはDB連携の部分で慣れてくればNext.jsでもいいのかもなぁ。。