Yanonoblog!

こつこつと

useStateを最新のReactドキュメントから学ぶ

はじめに

本記事では「モダンJavaScriptの基本から始める React実践の教科書」で学んだ内容と別途気になって調べた内容や知識も含めアウトプットしています。

詳細は2023年の3月にリリースされた新しいReactの公式ドキュメントを参照してまとめています。

書籍に記載されている内容を順序立ててまとめるというよりは、整理しておきたい周辺の知識と深ぼった内容を雑多に書いています。

超基礎的な内容です!

State

State(状態)はReactコンポーネントの内部に保持されるデータであり、コンポーネントの状態や振る舞いを表す値です。StateはReactの機能の一部であり、コンポーネント内で変更可能な値を管理するために使用されます。

コンポーネントレンダリングされたり更新されたりするとき、Stateの値が変更されると、コンポーネントは再レンダリングされます。

useState

Reactのフック(Hook)の一つであり、関数コンポーネント内で状態を管理するために使用されます。

トップレベルでuseStateをインポートします。

import { useState } from 'react';
Reactの内部イメージ
function useState(initialState) {
  // 状態の変数を定義し、初期値を設定する
  let state = initialState;

  // 状態を更新する関数を定義する
  function setState(newState) {
    state = newState;
    // コンポーネントの再描画をトリガーする
    // これにより、状態の変更が反映される
    // (厳密には内部のメカニズムで再描画が行われる)
  }

  // 状態の変数と状態を更新する関数を返す
  return [state, setState];
}

パラメーター

useStateは配列の分割代入を用います。

// const [状態値, 状態更新する関数]  = useState(初期値);

const [age, setAge] = useState(25);

上記の例では初期値をuseStateの引数に25を渡すとage変数に25が代入されます。

useStateの引数は、最初のレンダリングの後は無視されます。

set

setによって返される関数を使用すると、状態useStateを別の値に更新し、再レンダリングをトリガーします。

下記はcountの初期値を0とし、setCount関数を使ってcountの値を加算して更新するコード例です。

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

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(prevCount => prevCount + 1)}>Increment</button>
    </div>
  );
}

予備知識

  • **Hooksは最上位レベルでしか使えない**

    「useState」は、コンポーネントまたは独自のフックの最上位レベルで呼び出す必要があります。

    ループや条件分岐内で呼び出すことはできません。

    必要な場合は、新しいコンポーネントを作成し、そこに状態を移動させる必要があります。

  • Strictモードでは、Reactはイニシャライザー関数が2回呼び出される Reactはイニシャライザー関数を2回呼び出すため、偶発的な不純物を見つけやすくします。 この動作は開発時にのみ影響し、本番環境では無視されます。

注意点 - Reactの状態更新は非同期のバッチ処理として行われる

この実装では、setCount(count + 1)が3回呼び出されていますが、カウントが実際に3回分の数字が加算されるわけではありません。これは、setCount関数による状態更新が非同期で行われるためです。

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

  function handleClick() {
    setCount(count + 1);
    setCount(count + 1); 
    setCount(count + 1);
  }
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={handleClick}>Increment</button>
    </div>
  );
}

複数回のsetCount関数の呼び出しは、同じバッチ内でまとめられて非同期処理されます。

そのため、連続したsetCount関数の呼び出しでは、前の呼び出しの結果を反映させる前に次の呼び出しが行われるため、最終的には1回の状態更新しか行われません。

3回分の数字が加算された結果を得たい場合は、前回の値を基に値を増やすアップデーター関数を使用する必要があります。

setCount関数を使用して状態を更新する際は、関数を渡すことで正確な更新が行われます。

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

  function handleClick() {
    setCount(prevCount => prevCount + 1);
    setCount(prevCount => prevCount + 1);
    setCount(prevCount => prevCount + 1);
  }
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={handleClick}>Increment</button>
    </div>
  );
}

参考

続く…

コメント

本記事の内容は以上になります!

書籍の続きのアウトプットも随時更新したいと思います。


プログラミングスクールのご紹介 (卒業生より)

お世話になったプログラミングスクールであるRUNTEQです♪

https://runteq.jp/r/ohtFwbjW

こちらのリンクを経由すると1万円引きになります。

RUNTEQを通じて開発学習の末、受託開発企業をご紹介いただき、現在も双方とご縁があります。

もし、興味がありましたらお気軽にコメントか、TwitterのDMでお声掛けください。

https://twitter.com/outputky