5
1

More than 1 year has passed since last update.

React の state と useState について調べ直す

Last updated at Posted at 2022-12-20

React は UI を作るライブラリですが、HTML などとは違って単に見た目をマークアップするだけのものではありません。先にHTML を触っていた私にとってはその点が少し難しかった記憶があります。

今回は React のフックである useState についてまとめていきます。

▼ React の基本を復習したい方はこちらもご覧ください

state とは

日本語に直訳すると「状態」ですね。
公式ドキュメント によると、コンポーネントの「記憶」 のことだそうです。

例えばショッピングサイトを React で構築したとしましょう。

コンポーネントはユーザーの操作によって画面に表示されるものを更新するでしょう。検索バーに商品名が打ち込まれれば検索結果のページを表示し、ページの下にある「次へ」ボタンが押されると次のページを表示します。「カートに入れる」を押されればカートに入っている商品の個数を表すアイコンを表示する必要がありますね。

この場合、React のコンポーネントは「検索ワード」「現在の商品ページ」「カートに入った商品の個数」を記憶しているということになります。

コンポーネントが保持していないといけない値 = state という感じでしょうか。

useState とは

React で state を管理するためのフックです。

▼ フックってなに? と思った方はこちらもご覧ください。

state を管理したいだけなら、一見ただ変数を作って値を保存すればいいだけのような気もします。しかし以下の理由でうまくいきません。

  1. React が再レンダリング行った際に値が失われる
  2. 変数の値が変更されてもレンダリングは起こらないため、 state を変更しても反映されない、という状況になる

つまり state を使うためには、

  1. 再レンダリングされても値が失われない
  2. 再レンダリングのトリガーになる

という2つの条件が必要であり、それらを叶えてくれるのが useState というわけです。

useState は state を保存し、さらに state setter function(ステートを設定し直す関数)を作ります。 state setter function が動作することで再レンダリングが起きます。

useState の使い方

import { useState } from 'react';
import { sculptureList } from './data.js';

export default function Gallery() {
  const [index, setIndex] = useState(0);

  function handleClick() {
    setIndex(index + 1);
  }

  let sculpture = sculptureList[index];
  return (
    <>
      <button onClick={handleClick}>
        Next
      </button>
      <h2>
        <i>{sculpture.name} </i> 
        by {sculpture.artist}
      </h2>
      <h3>  
        ({index + 1} of {sculptureList.length})
      </h3>
      <img 
        src={sculpture.url} 
        alt={sculpture.alt}
      />
      <p>
        {sculpture.description}
      </p>
    </>
  );
}

// 引用: https://beta.reactjs.org/learn/state-a-components-memory

useState をはじめとするフックはコンポーネントの一番上で呼び出す必要があります。ドキュメントによるとファイルの先頭でモジュールをインポートするようなものだそうです。

useState を使うということはコンポーネントに「この値を覚えておいてね」と伝えることです。

const [index, setIndex] = useState(0);

名前は [値, set値] とするのが一般的です。一般的な命名規則に沿っておけばまず混乱は招かないでしょう。

useState が受け取っている引数は 初期値 です。この例だと 0 ですね。 index の値は初期状態だと 0 になるということです。

複数の state を持たせる

複数の state を持たせることもできます。

export default function Gallery() {
  const [index, setIndex] = useState(0);
  const [showMore, setShowMore] = useState(false);

  function handleNextClick() {
    setIndex(index + 1);
  }

  function handleMoreClick() {
    setShowMore(!showMore);
  }

  let sculpture = sculptureList[index];
  return (
    <>
      <button onClick={handleNextClick}>
        Next
      </button>
      <h2>
        <i>{sculpture.name} </i> 
        by {sculpture.artist}
      </h2>
      <h3>  
        ({index + 1} of {sculptureList.length})
      </h3>
      <button onClick={handleMoreClick}>
        {showMore ? 'Hide' : 'Show'} details
      </button>
      {showMore && <p>{sculpture.description}</p>}
      <img 
        src={sculpture.url} 
        alt={sculpture.alt}
      />
    </>
  );
}

// 参考: https://beta.reactjs.org/learn/state-a-components-memory

ただし2つの state を同時に変更している場合が多いな…と思ったら、1つにまとめることを検討した方がいいでしょう。

state は独立している

例えば同じコンポーネントを2カ所でレンダリングしている場合、それぞれの state は別々に保存されます。

import Gallery from './Gallery.js';

export default function Page() {
  return (
    <div className="Page">
      <Gallery />
      <Gallery />
    </div>
  );
}

// 引用: https://beta.reactjs.org/learn/state-a-components-memory

スクショを撮影した State: A Component's Memory で実際に触れるので試してみてください。

まとめ

  • state はコンポーネントの記憶であり、コンポーネントが保持していないといけない値
  • useState は React で state を管理するためのフック
  • useState が受け取っている引数は初期値
  • useState を複数回使って複数の state を持たせることもできる
  • state は独立しているので同じコンポーネントを2カ所でレンダリングしている場合、それぞれの state は別々に保存される

参考資料

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1