はじめに
Rectを勉強し始めたのだけど、
useStateとuseReducerの違いがよくわからない!!
useStateもuseReducerも状態を扱うフックだよ!
今回は、これらについて違いを意識しながら学んでいこう!
今回作るもの
今回は以下のようなカウントアップ機能を実装していきます。
useState、useReducerそれぞれで同じ機能を作って比較してみましょう。
useStateとuseReducer(状態のフック)
useStateとuseReducerは状態(state)を管理するフックで、これらを使用することでコンポーネントは内部状態をもち、その状態の変化に応じて画面表示を変更することができます。
useState
useState()で一つの新しい状態を作成することができます。
引数に渡したものが初期状態になります。
useState()の戻り値は配列で、配列の一つ目の要素が状態を保持する変数、二つ目が更新関数になります。更新関数を呼ぶことで状態が変化し、コンポーネントは再レンダリングされます。
const [状態,更新関数] = useState(初期状態)
useReducer
useReducerもuseStateと同様に状態(state)を管理するフックになります。
useReducerを使うことで複雑な状態をシンプルに記述することができます。
useStateは更新関数に直接更新後の値を記載するのに対して、useReducerは変数を宣言する時に、stateの更新方法をあらかじめ定義しておくことができます。
useReducerでは更新関数(dispatch)にactionと呼ばれるデータを渡すことで状態を更新できます。
dispatchが呼ばれると、更新前の状態とactionをreducer()に渡し、reducerが現在の状態とactionを元に次の状態を決定します。
reducer(更新前の状態,action) {
return 更新後の状態
}
const [状態,dispatch] = useReducer(reducer,reducerに渡す初期状態)
useStateの使い方
const [count, setCount] = useState(0);
コンポーネントの内部で状態管理した変数をuseState()を使って宣言していきます。
今回の場合は、画面に表示する数字(count)を管理していきます。
<button onClick={() => setCount(count - 1)}>-</button>
左辺のcountは管理する変数、setCountはcountの値を更新するための関数です。
上記のようにsetCountを呼び出してcountを更新していきます。
右辺のuseState()の引数は初期値です。上記の場合、countの初期値は0になります。
完成コード
カウントアップ機能を実装すると以下になります。
初期値はpropsで100を渡しています。
import { useReducer, useState } from "react";
// useState
type CounterProps = {
value: number;
};
export const Counter1 = (props: CounterProps) => {
const [count, setCount] = useState(props.value);
return (
<>
<h3>useState</h3>
<p>{count}</p>
<button onClick={() => setCount(count - 1)}>-</button>
<button onClick={() => setCount(count + 1)}>+</button>
<hr />
</>
);
};
};
import React from "react";
import ReactDOM from "react-dom/client";
import { Counter1 } from "./components/Counter";
const rootElement = document.getElementById("root")!;
const root = ReactDOM.createRoot(rootElement);
root.render(
<React.StrictMode>
<Counter1 value={100} />
</React.StrictMode>
);
useReducerの使い方
const [count, dispatch] = useReducer(reducer, value);
useReducer宣言の基本的な書き方は上記になります。
(state,action) => newStateの型のreducerを引数にとります。
今回の場合、reducerの記述は以下になります。
type Action = "MINUS" | "PLUS" ;
const reducer = (currentCount: number, action: Action) => {
switch (action) {
case "PLUS":
return currentCount + 1;
case "MINUS":
return currentCount - 1;
default:
return currentCount;
}
};
dispatchはreducerを実行するための関数になります。dispatch(action)でreducerメソッドが実行されstateが更新されます。
<button onClick={() => dispatch("MINUS")}>-</button>
<button onClick={() => dispatch("PLUS")}>+</button>
初めて見た際は混乱しがちですが、宣言構文、reducer関数、dispatch関数の引数の関係をよく見て理解していきましょう。
完成コード
import { useReducer } from "react";
// useReducer
type Action = "MINUS" | "PLUS" ;
const reducer = (currentCount: number, action: Action) => {
switch (action) {
case "PLUS":
return currentCount + 1;
case "MINUS":
return currentCount - 1;
default:
return currentCount;
}
};
export const Counter2 = (props: CounterProps) => {
const { value } = props;
const [count, dispatch] = useReducer(reducer, value);
return (
<>
<h3>useReducer</h3>
<p>{count}</p>
<button onClick={() => dispatch("MINUS")}>-</button>
<button onClick={() => dispatch("PLUS")}>+</button>
<hr />
</>
);
};
import React from "react";
import ReactDOM from "react-dom/client";
import { Counter2 } from "./components/Counter";
const rootElement = document.getElementById("root")!;
const root = ReactDOM.createRoot(rootElement);
root.render(
<React.StrictMode>
<Counter2 value={100} />
</React.StrictMode>
);
終わりに
本記事はここまでとなります。
最後に私がReact学習に使用したおすすめ教材を紹介します。
以下の2つのUdemyがおすすめです。書籍よりもずっと効率よく必要なスキルを取得できます。多くの人に愛されベストセラーを獲得しています。もしよかったら活用してみてください!
ご覧いただきありがとうございました。ご指摘等がございましたら頂けますと嬉しいです。
引き続き、プログラミングについて定期的に発信していきますのでよろしくお願いします!
また、もしよろしければtwitterもフォローしていただけると嬉しいです!🐢
コメント