ReactのuseStateの使い方!解説と注意点【サンプルコード9個】

React React

今回はReactのuseStateの使い方について書いてみました。
サンプルコードで検証しているReactのバージョンは17.0.2になります。

ReactのuseStateの使い方について

ReactのuseStateは変数の状態を管理するために使います。
useStateで作成した変数は「変数の内容が変わると画面の表示も変わる」といったように内容が同期されます。

useStateを使用して、変数を宣言するには下記のように使用します。
関数コンポーネントでコンポーネントを作成しました。

import React, { useEffect, useState } from 'react'

export const TestUseState = () => {
  const [email, setEmail] = useState()

  useEffect(() => {
    setEmail("test@example.com")
  }, [])

  return (
    <div className="m-3 col-4">
      <div>useStateのテスト</div>
      <div className="card">
        <div className="card-body">
          <div>メールアドレス:{email}</div>
        </div>
      </div>
    </div>
  )
}

export default TestUseState

関数コンポーネントの最初に下記のようにuseStateを使って、変数を宣言しています。
左側(email)は値を保持するための変数で、右側(setEmail)が値を更新するための関数です。

const [email, setEmail] = useState()

useEffectは画面が表示された後に処理を実行することができるReactの機能です。
今回は、そこでemail変数の内容を更新しています。

useEffect(() => {
  setEmail("test@example.com")
}, [])

こうすることで、email変数の値が更新され、画面に表示される内容も設定したものになります。
画面に表示しているのは、下記のように中括弧でemailを囲んでいるところです。

<div className="card-body">
  <div>メールアドレス:{email}</div>
</div>

実際に画面を確認すると、下記のように表示されていることが確認できました。

次項では、ただの文字列の他に配列やオブジェクトもuseStateを使って状態管理してみます。

useStateで値を初期設定する

値を初期で入れておく場合は、定義時にuseStateの引数で渡すといいです。

const [email, setEmail] = useState("yamada.taro@examle.com")

これで、最初からemail変数に値が入った状態になります。
その後は右側の値を更新する関数(setEmail)で、更新可能です。

useStateを使用したサンプル

それぞれの値をuseStateで定義して、画面に表示してみました。
使っている箇所のコードのみまとめました。

文字列を使ってみる

先ほどのサンプルと同じです。
定義は下記のようになります。

const [email, setEmail] = useState()

その後に、下記のように値の設定が可能です。

useEffect(() => {
  setEmail("test@example.com")
})

数値を使ってみる

定義は下記のようになります。

const [number, setNumber] = useState()

その後に、下記のように値の設定が可能です。

useEffect(() => {
  setNumber(10)
})

論理値を使ってみる

定義は下記のようになります。

const [testBool, setTestBool] = useState()

その後に、下記のように値の設定が可能です。

useEffect(() => {
  setTestBool(true)
})

配列を使ってみる

定義は下記のようになります。

const [scores, setScores] = useState([])

その後に、下記のように値の設定が可能です。

useEffect(() => {
  setScores([10, 20, 30, 40, 50, 60])
})

ちなみに画面表示する場合は、下記のようにmapを使用すると便利です。

<div className="card-body">
  点数:
  {scores.map((value) => {
    return "[" + value + "] "
  })}
</div>

オブジェクトを使ってみる

定義は下記のようになります。

const [user, setUser] = useState({
  name: '',
  age: '',
  address: '',
})

その後に、下記のように値の設定が可能です。

useEffect(() => {
  setUser({
    name: 'taro',
    age: '30',
    address: '福岡県博多区3',
  })
})

画面表示する時には、作成したオブジェクトのプロパティにアクセスすると表示できます。

<div className="card mt-2">
  <div className="card-body">
    <div>ユーザー名:{user.name}</div>
    <div>年齢:{user.age}</div>
    <div>住所:{user.address}</div>
  </div>
</div>

useStateで管理している配列を更新する

数値や文字列など、単純なデータならセットする関数に引数に渡すだけで処理できます。
配列やオブジェクトを扱うときには注意が必要です。

元の配列に値を追加する

元の配列に値を追加する場合です。
下記のように配列をスプレッド構文でコピーすると同時に、値を追加します。
その後に設定する関数に渡すと良いです。

let newScores = [...scores, 100, 200]

setScores(newScores)

配列を上書きする

配列を上書きする場合は、新規に作った配列を渡すと良いです。

const newScores = [55, 77, 99]

setScores(newScores)

スプレッド構文について

useStateで管理しているオブジェクトを更新する

次はオブジェクトを更新する場合です。

オブジェクトを上書きする

新しいオブジェクトを作成して、渡すと内容が上書きされます。

const newUser = {
  name: 'hanako',
  age: '22',
  address: '東京都八王子市'
};
setUser(newUser)

オブジェクトのプロパティ値を更新する

オブジェクトの一部の値を更新したい場合です。
下記のようにスプレッド構文を使用してオブジェクトをコピーすると同時に、プロパティの値を更新します。

setUser({...user, name: 'hoge'})

useStateを使う時に気をつけるところは?

useStateで値が変わるまで、時間差があります
値を設定する関数に、引数を渡しても、すぐに変わるわけではありません。

例えば、下記のように初期値でemail変数に「yamada.taro@examle.com」を入れています。

const [email, setEmail] = useState("yamada.taro@examle.com")

その後にボタンを押した場合に、下記の関数を実行します。
関数を実行した後にコンソールログでemail変数の内容を出力しました。

const changeData = () => {
  setEmail("hogefuga@example.com")
  console.log(email)
}

そうすると、下記のようにボタンを押した1回目は、コンソール出力には「yamada.taro@examle.com」が設定されています。(画面の表示は変わりました)
2回目に押すと「hogefuga@example.com」に変わりました。

ReactのuseStateは、すぐに値が反映されない

このように、すぐに値が反映されないので、反映されると思ってコードを書くと思わぬバグにハマってしまいます。
この挙動には注意して使うようにしていきましょう。

コメント

タイトルとURLをコピーしました