📘

useStateについて理解する(React)

2023/02/26に公開

概要

Reactのコンポーネントの中で状態を管理したい時に、useStateを使う。

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

useState関数を実行すると、状況に応じて変化する値(state)と、stateを更新するための関数(setState)を返却します。

コンポーネントの初回の描画時に返却される state は useState に第1引数として渡した値 (initialState) と等しくなります。

setState 関数を実行すると、コンポーネントの再レンダーをスケジューリングします。
setStateを実行したときの他の全ての処理が終わった後に、再レンダリングが開始されます。

setState(newState);

setState実行後にコンポーネントを再描画した後は、 useState から返却されるstateはsetStateで更新された状態になっています。

stateが更新されるタイミング

import {useState} from "react"

export default function Index () {
    const [count, setCount] = useState(1);
    const onButtonClick = () => {
      setCount((preCount) => preCount + 1);
      alert(count);
    }

  return (
    <div>
      <button onClick={onButtonClick}>押して!</button>
    </div>
  )
}

ボタンを押すとブラウザにダイアログが表示されるプログラムです。
setConutでcountを足しているので「2」が表示されるような気がするが実際には「1」が表示される

解説を下記する。

ボタンを押したときの動きとしては、下記になる

  1. setState関数を実行し、memoryの状態を更新して、再レンダリングの予約をする
  2. ブラウザにアラートで「1」と表示される*
  3. 再レンダリング実行時に、useStateの返却値であるstateにmemoryの状態を代入する

*setCountを実行して、useStateから返却されるstateが更新されるタイミングは、コンポーネントの再描画時なので、alertを実行するタイミングではstate(count)は変更されないので、「1」とブラウザに出力されます。

https://ja.reactjs.org/docs/hooks-reference.html#usestate

注意点

  • コンポーネント内だけで状態を持っている.下のような場合はcountが各コンポーネントで状態管理されている

import { useState } from 'react';

export default function MyApp() {
  return (
    <div>
      <h1>Counters that update separately</h1>
      <MyButton />
      <MyButton />
    </div>
  );
}

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

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <button onClick={handleClick}>
      Clicked {count} times
    </button>
  );
}
  • 状態を管理しているのはin memoryである。stateは単にin memoryを確認して代入した変数である
  • コンポーネントの状態とuseStateからの返却値(state, setState)が更新するタイミングがずれることを意識する

Discussion