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
で加算、減算を行っている。
2が加算された後に1減算されたことが分かる。
useReducerを使うことでuseStateではできない単体テストができる。そのためバグを事前に防ぐことができる。また、複数名で開発を行う際、useReducerの場合は更新の仕方自体記述されているため、不用意に変更されることがない。