4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【React】UseReducerの使い方

Posted at

useReducerとは??

useReducerは、useStateと同じく値を管理できるフック
useReducer:更新を状態側で行う
useState:更新は利用者側で行う

useStateの場合

ここではボタンを押すとカウントアップするプログラムを作成した

import { useState } from "react";

const Example = () => {
  const [state, setState] = useState(0);

  const countUp = () => {
    //useStateを使う場合は呼び出し時(使うとき)に処理を記述する
    setState((prev) => prev + 1);
  };

  return (
    <>
      <h3>{state}</h3>
      <button onClick={countUp}>カウントアップ</button>
    </>
  );
};
export default Example;

カウントアップボタンをクリックするとcountUp関数が呼ばれる
その中でsetStateが使用され、useStateの場合、呼び出し時に setState((prev) => prev + 1);という処理を記述して、カウントアップをしている

useReducerの場合

  • useReducerの書き方
const [state, dispatch] = useReducer(reducer, initialState);

reducer:stateを更新するための関数。stateとactionを受け取って新しいstateを返す。
initialState:stateの初期値

initialStateはuseState()の()の中身の値(初期値)の宣言と同じ

import { useReducer } from "react";
const Example = () => {
    //useReducerを使う場合は定義の時点でstateをどのように更新するか、処理内容を書く
    const [state, dispatch] = useReducer(prev => prev + 1, 0);
    const rcountUp = () => {
        dispatch();
    };

    return (
        <>
          <h3>{state}</h3>
          <button onClick={rcountUp}>カウントアップ</button>
        </>
    );
};

カウントアップボタンをクリックするとrcountUp関数が呼ばれる
useReducer内でprev => prev + 1という処理が記述されているため、dispatchを呼ぶときは処理を記述しなくても良い。

useReducerで条件分岐を行う

カウントアップとカウントダウンを実装する

import { useReducer } from "react";
const Example = () => {
  const [state, dispatch] = useReducer((prev, {type}) => {
      if(type === '+'){
        return ++prev;
      }else if(type === '-'){
        return --prev;
      }
  }, 0);

  const rcountUp = () => {
    dispatch({ type: "+"});
  };

  const rcountDown = () => {
    dispatch({ type: "-"});
  };

  return (
    <>
      <h3>{state}</h3>
      <button onClick={rcountUp}>カウントアップ</button>
      <button onClick={rcountDown}>カウントダウン</button>
    </>
  );
};

export default Example;

選択されるボタンによって{type:'+'}または{type:'-'}が引数として渡される。
引き数をif文で分岐させ、+であればカウントアップ、-であればカウントダウンを行う。

useReducerで引数を二つ渡す

import { useReducer } from "react";
const Example = () => {
  const [state, dispatch] = useReducer((prev, { type, step }) => {
      switch (type) {
      case "+":
        return prev + step;
      case "-":
        return prev - step;
      default:
        throw new Error("実行できませんでした");
  }, 0);

  const rcountUp = () => {
    dispatch({ type: "+", step: 2 });
  };

  const rcountDown = () => {
    dispatch({ type: "-", step: 1 });
  };

  return (
    <>
      <h3>{state}</h3>
      <button onClick={rcountUp}>カウントアップ</button>
      <button onClick={rcountDown}>カウントダウン</button>
    </>
  );
};

export default Example;

引き数を2つ渡すには、上記と同様にカウントアップであれば{type:'+', step:'2'}とする。カウントアップをする際に+2をするため、stepに2を渡している。カウントダウンであれば{type:'-', step:'1'}となる。
useReducer内の処理で+,-で分岐し、渡されたstepで加算、減算を行っている。

カウントアップをクリックした後↓
スクリーンショット 2022-10-27 120457.png

カウントアップクリック後にカウントダウンをクリックした後↓
スクリーンショット 2022-10-27 120513.png

2が加算された後に1減算されたことが分かる。

useReducerを使うことでuseStateではできない単体テストができる。そのためバグを事前に防ぐことができる。また、複数名で開発を行う際、useReducerの場合は更新の仕方自体記述されているため、不用意に変更されることがない。

4
4
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
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?