📖

【備忘録】React Hooksの使い方まとめ

2023/09/25に公開

はじめに

自分が学習したReact Hooks(useState, useEffect, useContext, useRef, useReducer)の
使い方について、備忘録を兼ねて簡単にまとめたいと思います。

React Hooksについて

React Hooksとは、コンポーネントから様々な機能を使えるように用意されたAPIのことです。
React Hooksはもちろん組み合わせて独自のHooksを作成することも可能です。

https://ja.react.dev/reference/react

React Hooksの使い方

上記の公式ドキュメントにもある通り、React Hooksは沢山ありますが、今回はuseState,useEffect,useContext,useRef,useReducerの5つのHooksの使い方についてまとめていきたいと思います。

useState

useStateは、コンポーネントに状態変数(state)を追加するためのHooksとなります。
useStateを用いて定義されるset関数(下記定義方法でいうsetState関数)を用いて、コンポーネント内の状態を変更することで再レンダリングが行われます。

https://ja.react.dev/reference/react/useState

定義方法は以下の通りです。

const [ state, setState ] = useState(/* 初期値 /*);

使用例は以下の通りです。

example.jsx
import { useState } from "react";

const Example = () => {
  const [ count, setCount ] = useState(0);
 
  const handleClick = () => {
    setCount(count + 1);
  };
  
  return (
    <>
      <p>カウント数:{count}</p>
      <button onClick={handleClick}>+</button>
    </>
  );
};

export default Example;

useStateを用いて、初期値0のcountsetCount関数を定義します。
ボタンが押された際に呼ばれるhandleClick関数内で、setCount関数を用いてcountに+1することで、画面が更新され、値が1増えて表示されます。

useEffect

useEffectはレンダによって引き起こされる副作用を指定するHooksとなります。
第一引数に実行する関数、第二引数に依存関係(第一引数で渡された関数を実行するトリガ)を配列で渡します。

https://ja.react.dev/reference/react/useEffect

定義方法は以下の通りです。

useEffect(() => { /* 処理 */ }, [/* 依存関係 */]);

使用例は以下の通りです。

example.jsx
import { useEffect } from "react";

const Example = () => {
  
  useEffect(() => {
    console.log("useEffect");
  }, []);
  
  return (
    <>
      <p>useEffectの使い方</
    </>
  );
};

export default Example;

上記コードではページがロードされたタイミングでのみ、useEffectに渡した関数が実行され、コンソールにuseEffectが1回表示されます。
※Strict Modeが有効になっている場合は、最初にクリーンアップロジックが実行されるため、useEffectは2回表示されます。

useContext

useContextはコンポーネントのツリーのどの階層であっても、グローバルにデータを受け渡すためのHooksとなります。
createContextuseContextを用いてグローバルにデータを受け渡します。

https://ja.react.dev/reference/react/useContext

定義方法は以下の通りです。

// createContextの定義方法例
const ThemeContext = createContext(/* 受け渡したいデータ */);

// useContextの定義方法例
const themeContext = useContext(ThemeContext);

使用例は以下の通りです。

main.jsx
import React, { createContext } from "react";
import ReactDOM from "react-dom/client";
import App from "./App.jsx";
import "./index.css";

const personalInfo = {
  name: "hoge",
  age: 30,
};

const PersonalContext = createContext(personalInfo);

ReactDOM.createRoot(document.getElementById("root")).render(
  <PersonalContext.Provider value={personalInfo}>
    <React.StrictMode>
      <App />
    </React.StrictMode>
  </PersonalContext.Provider>
);

export default PersonalContext;
App.jsx
import { useContext } from "react";
import PersonalContext from "./main";

function App {
  const personalInfo = useContext(PersonalContext);
  
  return (
    <>
      <p>{personalInfo.name}<p>
      <p>{personalInfo.age}<p>
    </>
  );
}

export default App;

main.jsxで定義されたperonalInfoのデータを受け渡すため、createContextを用いてPersonalContextを作成します。子コンポーネント以下の情報を渡すため、<PersonalContext.Provider value={personalInfo}><PersonalContext.Provider>のタグで囲みます。
App.jsxではuseContextを使用して、親コンポーネントであるmain.jsxのpersonalInfoの情報を取得します。

useRef

useRefはDOMを参照し、要素へアクセスするためのHooksとなります。
useRefはレンダリングを起こさずに値の保持ができるため、レンダリングさせたくない場合に用います。

https://ja.react.dev/reference/react/useRef

定義方法は以下の通りです。

const ref = useRef(/* 初期値 */);

使用例は以下の通りです。

example.jsx
import { useRef } from "react";

const Example = () => {
  const ref = useRef();

  const handleRef = () => {
    console.log(ref.current.value);
  };
  
  return (
    <>
      <input type="text" ref={ref}>
      <button onClick={handleClick}>button</button>
    </>
  );
};

export default Example;

アクセスしたいDOM要素のrefにuseRefで定義した変数refを設定することで、
変数refを用いてアクセスすることができます。
上記コードでは、ボタンをクリックすることで、input要素に入力されている値をコンソールに出力することができます。

useReducer

useReducerは、useStateと同様にコンポーネントに状態を追加するためのHooksとなります。
特に管理する状態が複数となり、複雑な状態変更管理を行う場合に用いられます。
第一引数にreducer(状態を変更するための関数)を、第二引数に管理する状態の初期値を代入します。

https://ja.react.dev/reference/react/useReducer

定義方法は以下の通りです。

const [ state, dispatch ] = useReducer(reducer, {/* 状態の初期値 */})

使用例は以下の通りです。

import { useReducer } from "react";

const reducer = (state, action) => {
  switch (action.type) {
    case "increment":
      return state + 1;
    case "decrement":
      return state - 1;
    default:
      return state;
  }
};

const Example = () => {
  const [ state, dispatch ] = useReducer(reducer, 0)

  const handleRef = () => {
    console.log(ref.current.value);
  };
  
  return (
    <>
      <p>カウント: {state}</p>
      <button onClick={() => dispatch({ type: "increment" })}>+</button>
      <button onClick={() => dispatch({ type: "decrement" })}>-</button>
    </>
  );
};

export default Example;

reducer関数はstateとactionを引数にとり、関数内でactionの種別に応じてstate(状態)を変更します。このreducer関数とstateの初期値をuseReducerの引数に渡すことで、状態を管理することができます。状態を変更する場合は、dispatch関数を用いて変更を行います。

最後に

簡単ながら、useState,useEffect,useContext,useRef,useReducerの5つのHooksの使い方についてまとめてみました。この他にも沢山のHooksがあります。
レンダリングの最適化で用いるHooksについては下記記事にてまとめておりますので、よろしければご参照ください。
最後まで記事を読んでいただきありがとうございました。

https://zenn.dev/snow_swallow/articles/ce3c0d1fa4b291

参考文献

https://ja.react.dev/
https://qiita.com/seira/items/fccdf4e73c59c491558d
https://choippo.com/react-hook-useref/#index_id1
https://takayamato.com/react-usereducer/

Discussion