TS初めてのTypeScript

Day 5React/Next.jsの超入門

useStateの型と状態更新・イベント

画面の状態をuseStateで持ち、型を推論させつつ、クリックや入力のイベントを型安全に扱う。

画面に「覚えておく値」を持たせるのがuseState

ボタンを押すたびに数が増えるカウンター、入力欄に打った文字。こうした「時間とともに変わり、画面に反映したい値」を状態(state)と呼びます。Reactではという仕組みで状態を持ちます。ふつうの変数ではなくuseStateを使う理由は、値を更新したときにReactが自動で画面を描き直してくれるからです。

TSX
import { useState } from "react";

function Counter() {
  // count が今の値、setCount が更新する関数
  // 初期値 0 を渡すと、count の型は number と推論される
  const [count, setCount] = useState(0);

  return (
    <button onClick={() => setCount(count + 1)}>
      {count} 回押した
    </button>
  );
}
useStateの基本。返り値は[今の値, 更新する関数]の2つ組

状態は直接書き換えない

count = count + 1 のように直接代入しても、Reactは変化に気づかず画面を更新しません。必ず更新関数 setCount を通します。setCountを呼ぶことが「画面を描き直して」という合図になります。

型は推論に任せ、必要なときだけ明示する

useState(0) のように初期値を渡すと、TypeScriptが「これはnumberだ」と自動で判断します(型推論)。多くの場合これで十分です。ただし、初期値がnullで後から値が入る場合など、推論では足りないときは山括弧で型を明示します。

TSX
type User = { id: number; name: string };

function Profile() {
  // 初期値 null だけだと「常にnull」と推論されてしまう
  // <User | null> で「Userかnull」と明示する
  const [user, setUser] = useState<User | null>(null);

  if (user === null) {
    return <p>読み込み中...</p>;
  }
  // ここでは user は User 型に絞り込まれている
  return <p>{user.name}</p>;
}
型を明示するケース。最初はnull、あとでUserが入る

イベントにも型がある

クリックや入力などの操作を「イベント」と呼び、それに応じて動く関数を書きます。入力欄の値を状態に反映する定番パターンを見てみましょう。イベントの引数にも型があり、e.target.value が文字列だとエディタが分かっているので、打ち間違いを防げます。

TSX
import { useState, type ChangeEvent } from "react";

function NameInput() {
  const [name, setName] = useState("");

  // e は入力イベント。型をつけると e.target.value が string と分かる
  function handleChange(e: ChangeEvent<HTMLInputElement>) {
    setName(e.target.value);
  }

  return (
    <div>
      <input value={name} onChange={handleChange} />
      <p>入力中: {name}</p>
    </div>
  );
}
入力イベント。ChangeEventの型で e.target.value が守られる
  • useStateは [今の値, 更新関数] の2つ組を返す。分割代入で受け取る
  • 更新は必ず更新関数(setXxx)を通す。直接代入は画面に反映されない
  • 初期値から型が推論される。null始まりなど足りないときだけ useState<型>() で明示する
  • イベント引数の型(例: ChangeEvent<HTMLInputElement>)をつけると e.target.value などが守られる

AIにはこう聞く

「入力欄の値をuseStateで管理し、onChangeで更新するReactコンポーネントを、TypeScriptで型もつけて書いて」と頼めば、イベント型まで含めて書いてくれます。生成されたコードで e の型が any になっていないかだけ自分でチェックしましょう。型がついていれば、AIが e.target.velue のように綴りを間違えても赤線で分かります。

状態はuseStateで持ち、更新は更新関数を通す。イベントには型をつける。この3つを押さえれば、動きのある画面の土台は作れます。

読んでも腑に落ちない所は、AIに噛み砕いてもらいましょう。

理解度チェック

答えられれば、面接で説明できる状態に一歩近づきます。

Q1

const [count, setCount] = useState(0) について、正しい説明はどれ?

Q2

初期値が null で、あとから User 型の値が入る状態を宣言したい。適切なのはどれ?

Q3

Reactで状態を直接書き換えず更新関数(setXxx)を使う理由を説明してください。

記述式です。まず自分の言葉で答えを考えてから、模範解答を開いて自己採点してください。