LoginSignup
18
8

【React】初学者がuseStateとuseEffectをまとめてみました。

Last updated at Posted at 2023-12-13

はじめに

こんにちは!
ガク@Necono_Engineerと申します!
プログラミングスクールRUNTEQで現在Ruby on Railsを中心に学んでいます。今回はポートフォリオ作成のためにReactを学んでいる過程で出会ったuseStateuseEffectについてまとめてみました!
1.jpg

プログラミング初学者のため、内容に誤りがある可能性がございます。
もし間違いがあればご指摘いただけると幸いです。

React Hooks

今回学んだuseStateuseEffectはReact Hooksの1つです。

React Hooksとは?

2017年の9月にリリースされたReact16.8からの機能です。
以前は、クラスコンポーネントでしか扱えなかった、Stateやライフサイクルの機能をHooksを使用することで関数コンポーネント取り付ける(Hook up)ことができます。

useState

特に頻繁に使用されるフックとしてuseStateがあります。
useStateを使用することで関数コンポーネント内でstate(状態)を保持することができるようになります。

使用方法

import { useState } from 'react';

トップレベルでuseStateをインポートすることで使用可能になります。

  • 状態(state)とその状態を更新する関数(setState)を定義します。
  • 初期値を設定します。
const [state, setState] = useState(false);
記述名 備考
state 現在の値
setState stateの状態を変更する関数
false 初期値

Stateとは?

Reactのコンポーネントは内部で「状態」を持つことができます。

状態

状態はアプリケーションやコンポーネントの現在の情報のことで、stateと呼ばれます。

Stateの流れ

  1. コンポーネントの状態を保存
  2. その状態が変更された時に自動的にコンポーネントを更新(再レンダリング)

例) クリックすると数字が+1されるCounterコンポーネント

import React, { useState } from 'react';

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

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

export default Counter;

Image from Gyazo
↑ コンポーネントが内部で保持するstateが更新されると、コンポーネントが再描画され画面上のUIが変化します。
上記のコードでは更新関数であるsetCountを呼び出すと状態が変化します。

<button onClick={() => setCount(count + 1)}>+1</button>

ボタンに onClick イベントハンドラーを追加し、クリックすると setCount 関数を呼び出して count の値を1増やすように設定しています。

更新関数(setのついたもの)は現在の count 値に 1 を加えた値で count を更新します。

setCount(count + 1)

そして、

<p>Current Count: {count}</p>

この{count}の部分で現在のcountの値をJavaScript変数として表示しています。(JSX構文内ではJavaScriptの式を使用でき、{ }で表現されます。)

このようにuseStateを使用することでコンポーネント内で動的な処理が可能になります!

useEffect

useEffectは、React コンポーネント内で副作用を実行するために使用されるフックです。

副作用

UIのレンダリングに直接関係しない操作を指します。
これには以下のようなものが含まれます

  • API からデータを取得する
  • タイマーをセットする
  • DOM ノードを直接操作する など。

依存配列

useEffect には、第2引数として「依存配列」を渡すことができます。

useEffect(() => {
  // 副作用を実行する処理を記述する
}, [依存配列]);
記述名 備考
副作用 第1引数
依存配列 第2引数
  • 依存配列が指定されている場合

配列内の値が変更されたときにのみ、副作用が再実行されます。
以下のコードでは(userId)が変化したときに、APIからユーザーのデータを取得するという副作用の処理を行います。

import React, { useState, useEffect } from 'react'; //useEffectの定義

function UserProfile({ userId }) {
  const [user, setUser] = useState(null);

  useEffect(() => {
    async function fetchUserData() {
      const response = await fetch(`https://api.example.com/users/${userId}`);
      const userData = await response.json();
      setUser(userData);
    }

    fetchUserData();
  }, [userId]);    // userIdが変更されたときのみこの副作用を実行

  return (
    <div>
      {/* ユーザーデータの表示 */}
      {user && <div>{user.name}</div>}
    </div>
  );
}

export default UserProfile
  • 依存配列が空の場合([])

useEffectはコンポーネントがマウントされた後に一度だけ実行されます。
その後、propsやstateの変更があってUIが再描画された場合(再レンダリング)でも副作用は再実行されません。

マウント

コンポーネントに対するDOMノードを作成、既存のDOMツリーに挿入し、webページ上にコンポーネントが初めて描画された時のことを言います。アンマウントはDOMノードが既存のDOMツリーから削除された時のことを言います。

以下のコードではコンポーネントがマウントされた時にタイマーをセットし、アンマウントされた時にクリアします。

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

function TimerComponent() {
  const [seconds, setSeconds] = useState(0);

  useEffect(() => {
    const intervalId = setInterval(() => {
      setSeconds(prevSeconds => prevSeconds + 1);
    }, 1000);

    return () => clearInterval(intervalId); // コンポーネントのアンマウント時にインターバルをクリア
  }, []); // 依存配列が空なので、マウント時にのみ実行される

  return <div>経過秒数: {seconds}</div>;
}
export default TimerComponent

Image from Gyazo

  • 依存配列が指定されていない場合:

副作用はコンポーネントの初回マウント時と、その後のすべての更新(再レンダリング)後に実行されます。stateやpropsのどの変更にも反応して副作用を実行します。
stateやpropsの更新 → UIの再描画 → 処理の実行の順番で行われ、コンポーネントが画面に表示されたときや更新されたときに特定のコードを実行することができます。

まとめ

useStateとuseEffectを調べていくにつれてからReactの基礎概念である状態、副作用、マウントなどについても少しだけですが知ることができました。実践でフックを適切に扱えるよう今後も学習を進め、Reactへの理解をさらに深めたいと思います!

参考文献

書籍

記事

18
8
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
18
8