【React】React Hooks を8つ紹介 これだけは押さえてほしい!

はじめに

Reactを学習しており、一度知識の整理と思ってつらつらと書いていきます。

今回はReact Hooksについて、押さえておきたいものを8つほど載せています。

Hooksを使い分ける目的としては不要なレンダリングを減らしてUXを向上することであるので、

使いこなせるようになりたいと思ってます。

では、さっそく紹介していきます。

・useState

Stateは状態のことを指します。画面上で変化する値を管理する際にuseStateを使います。

例えば、ログインの状態をtrue,falseの状態にする時や、

0の状態を1.2.3...とカウントアップしたい時にもuseStateを使います。

import { useState } from 'react' // hooksをインポート

function App(){

  const [count, setCount] = useState(0); // 初期値(0)を指定できる

  const handleClick = () => {
    setCount(count + 1); // クリック時にカウントアップ
  };

  return (
    <div>
      <button onClick={handleClick}>追加</button>
      <p>{ count }</p>
    </div>
  )
};
...

状態変数のcount(初期値0)に対し、ボタンをクリック(handleClick)するとカウントアップして、

新しいcountレンダリングされる処理を書いています。

ちなみに、ダメな書き方として

function App(){
  let count = 0;

  const handleClick = () => {
    count++;
  };

  return (
    <div>
      <button onClick={handleClick}>追加</button>
      <p>{ count }</p>
    </div>
  )
};
...

このように、useStateを使わない書き方では、ボタンをクリックした時に変数countはデータとしてはカウントアップされますが、レンダリングは行われないので表示は0のままになります。

レンダリングについて今回は詳しく説明しないので、わからない方は調べてみてください。

・useEffect

useEffectについては、第一引数にはコールバック関数、第二引数には配列を取ります。

useEffectは、レンダリング終了後に処理を実行したいときに使用します。

(レンダリング終了後の処理を副作用と呼びます)

変数aの状態が変わった時だけ処理を行う、mount時に処理を行う、リロード時に処理を行うなど、発火のタイミングを指定できるのが特徴です。

それでは先ほどのuseStateのコードを使用して、

import { useState, useEffect } from 'react' // hooksをインポート

function App(){

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

  const handleClick = () => {
    setCount(count + 1); 
  };

  //ここ↓
  useEffect(()=>{
    console.log("test");
  }, [count]);

  return (
    <div>
      <button onClick={handleClick}>追加</button>
      <p>{ count }</p>
    </div>
  )
};
...

useEffectの第二引数にとっているcountが変更されるたびに、第一引数のコールバック関数が走る処理を書いています。 (第二引数が空の場合はレンダリングごとに処理が走ります)

ちなみに、

useEffect(()=>{
    setCount(count + 1);
  }, [count]);

第二引数がcountで、第一引数のコールバック関数内でcountを変更する処理を書くと無限ループになり、笑顔になれます。(うっかりやりがち)

・useContext

useContextは状態管理に使われます。

Reduxと考え方はほぼ同じです。 (Reduxについては機会があれば記事にします)

コンポーネントツリー間でデータの受け渡しをする際、propsのバケツリレーをすることなく、contextからデータの受け渡しをすることができます。 Reduxではstoreにグローバルに受け渡しをしたいデータを格納しますが、React Hooks(useContext)を使えばcontextを作成する場所を指定することで、そこからデータを受け渡しすることができます。

propsバケツリレー

簡単に例を載せておきます。

src
├── App.jsx
└── components
    ├── component1.jsx  //子
    ├── component2.jsx  //孫
    └── component3.jsx  //ひ孫
import { createContext } from 'react'  // hooksをインポート
import Component1 from './components/component1';

// 例として、データuserを渡してみます。
const user = {
  name: "田中",
  age: 25,
};

export const UserContext = createContext(user); //contextを作成

function App(){
  return (
    <div>
      //UserContext.Providerタグで囲む(value忘れがちなので注意)
      <UserContext.Provider value={user}>
        <Component1 />
      </UserContext.Provider>
    </div>
  )
};

export default App;
import Component2 from './component2'

const Component1 = () => <Component2/>

export default Component1
import Component3 from './component3'

const Component2 = () => <Component3/>

export default Component2
import { useContext } from "react" // hooksをインポート
import { UserContext } from "../App" // 作成したcontextをインポート

const Component3 = () => { 
  const user = useContext(UserContext); //Contextを使う

  return (
    <div>
      <p>{ user.name }</p>
      <p>{ user.age }</p>
    </div>
  )
}

export default Component3

この例では、データuserAppより下のコンポーネントツリーに対して、contextを使って受渡できるようにしています。

コンポーネント構造

・受け渡ししたいデータに対してcreateContext

・受け渡しできる範囲を指定<HogeContext.Provider value={hoge}>

・データを使う場所でuseContext

・useRef

useRefrefはrefferenceで、文字通りではありますがタグの情報を”参照”することができます。 inputタグの入力情報などを取得する際に使用したり、そのほかにもタグの情報(高さ等)を取得したりすることができます。

import React, { useRef } from 'react'; // hooksをインポート

function App() {
  const ref = useRef(); // hooksを宣言
  
  const handleRef = () => {
    console.log(ref.current.value);
  };

  return (
    <div className="App">
      <input type="text" ref={ ref } /> // 参照したいタグにrefを指定
      <button onClick={handleRef}>クリック</button>
    </div>
  );
}

export default App;

上記の例ではinputタグのタグ情報の内、current.valueを取得しています。

useRefは中身が変更になってもそのことを通知しないということを覚えておいてください。 .currentプロパティを書き換えても再レンダーは発生しません。 DOMNoderefに割り当てたり割り当てを解除したりする際に何らかのコードを走らせたいという場合は、CallbackRefを代わりに使用してください。

引用:React公式

・useReducer

useReduceruseStateによく似ています。

ですので、useStateより使う機会が少ないかもしれませんが、複数の値にまたがる複雑なstateロジックがある場合や、前のstateに基づいて次のstateを決める必要がある場合にuseReducerを使用します。

useReducerを使えばコールバックの代わりにdispatchを下位コンポーネントに渡せるようになるため、複数階層にまたがって更新を発生させるようなコンポーネントではパフォーマンスの最適化にもなります。

引用:React公式

・useMemo

useMemoはパフォーマンス向上のために使用します。 useMemoを使うことで関数の結果(状態)をブラウザ側のメモリに保存することができます。(メモ化)

レンダリングをしても関数の結果が変わらない場合は再計算を行わず、保存して置いた結果を取得するのでパフォーマンス最適化につながります。

使い方としては、読み込みや処理が重いと感じたときに使います。

第一引数にはメモ化したい値を、第二引数には依存関係を指定します。 第二引数に指定した値が更新した場合、第一引数の値の再計算を行います。

・useCallback

useCallbackuseMemoと同じくパフォーマンス向上のために使用します。 useCallbackでは、関数をブラウザ側のメモリに保存することができます。

使い方としては、読み込みや処理が重いと感じたときに使います。

第一引数にはメモ化したい関数を、第二引数には依存関係を指定します。 第二引数に指定した値が更新した場合、第一引数の関数を発火させます。

useMemouseCallbackは、パフォーマンス向上になるからといって使いすぎるとメモリを圧迫するので、塩梅が必要です。

・カスタムhook

カスタムhookとは、use〇〇というようにHooksを自分でも作ることができます。 引数や返り値等も自由に設定でき、カスタムhook内でも他のReact Hooksを使用できます。

まとめ

以上、React Hooksのうち8つほど紹介をしました。

ざっくりとした理解の部分も多いので、これからももっとReactについてついて深掘っていきたいです。

最後まで読んでいただきありがとうございました。

参照

React公式reference