Tyotto good!

【React Hooks】useStateの基本を理解しよう

Posted: February 22, 2021

今回はReact Hooksで基本となるuseStateについて詳しく解説していきます🙌

useStateを使うと何ができるのか

useStateを用いることで、コンポーネントに状態(state)を持たせることができます。状態(state)とは、コンポーネントに管理され、プライベートであるべき値のことです。
この説明だとあまりピンとこないかもしれないので、例を見てみましょう。

useStateを用いた関数コンポーネント

以下は、ボタンのクリック回数を表示するコンポーネントです。

import React, { useState } from "react";

const UseStateExapmple: React.FC = () => {
  const [count, setCount] = useState(0);

  return (
    <>
      <h3>count : {count}</h3>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </>
  );
};

まず注目すべきは

const [count, setCount] = useState(0);

です。
ここで関数コンポーネントが持つstateを定義しています。

useStateの構文

上記の例からなんとなくわかるように、まずuseState を呼び出すと配列が返ってきます。
最初に格納されている値がstateの値で、その次にstateを更新するための関数が返されます。また、useStateの引数にはstateの初期値が入ります。
つまり関数コンポーネントでstateを扱いたければ以下のようにuseStateを呼び出せばよいことがわかるかと思います。

const [state, setState] = useState(initialValue);

stateの更新

stateを更新するには先ほどのuseStateの戻り値に格納されていたsetCount を使います。(※setXXX という命名は慣習であり、必ずその命名にする必要はありません。)
上記の例からsetCountを使っている箇所を見てみましょう。

<button onClick={() => setCount(count + 1)}>Click me</button>

この例ではbutton要素のonClickイベントが呼ばれる度にsetCount が呼び出されています。
stateを更新するにはsetXXX引数に更新後の値を入れます。例では、stateであるcountの値に+1しています。

  • コールバック関数でstateを更新する

なお、以前のstateを使用して新しいstateを計算するといった場合にはコールバック関数を用いてstateを更新することができます。

<button onClick={() => setCount((c) => c + 1)}>Click me</button>

コールバック関数の引数には更新前のstateが入るので、このコードでも同じようにstateを更新することができます。
これらを踏まえて、改めてコードを見てみると、ボタンをクリックする度にstateを更新する関数であるsetCountが呼び出されてstateであるcountを+1していることがわかります。
また、stateはその時の値を保持し、値に変更があればコンポーネントの再レンダリングを行うため、ボタンをクリックするごとに画面のクリック数の表示が変化します。

import React, { useState } from "react";

const UseStateExapmple: React.FC = () => {
  const [count, setCount] = useState(0);

  return (
    <>
      <h3>count : {count}</h3>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </>
  );
};

stateの初期化を遅延させる

コンポーネントがレンダリングされる度にuseStateが実行されます。この時、stateを初期化する計算にコストがかかる場合、毎回この計算を行っているとパフォーマンスに支障がでる可能性があります。
そこでuseState引数に関数を渡すことで初期レンダリング時に1度だけ初期化の計算を実行させることができます。そのため、2回目以降のレンダリングでは初期化する処理は呼び出されず、コストのかかる計算はスキップされます。

// useStateの引数に関数を渡す : 初期レンダリング時のみ実行される
const [state, setState] = useState(() => {
	// コストがかかる計算
  const initialState = expensiveComputation();
	// 戻り値が初期値となる
  return initialState;
});

まとめ

  • useState を用いることで関数コンポーネントの状態を管理することができる
  • useStateはstateとそれを更新する関数を返す
  • 関数をuseStateの引数に渡すことで2回目以降のレンダリング時に初期化を行わないようにできる

さらに詳しくuseStateを知りたい方は、useStateの注意点3選も見てください👀