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

Posted: 2021/2/23
React/
React Hooks

今回は 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 選も見てください 👀