Reactには、コンポーネント内で状態を管理するための機能が備わっています。しかし、複雑なアプリケーションを開発する場合、コンポーネント間で状態を共有する必要があります。そのために、Reduxなどの状態管理ライブラリを使用することが一般的ですが、Reduxを導入するとコードの複雑さが増し、学習コストも高くなります。
そこで、Reduxを使わずに状態管理をする方法を紹介します。
1. useContextフックを使う
Reactには、コンポーネントツリー全体で共有することができるグローバルな状態を管理するためのuseContext
フックがあります。このフックを使うことで、Reduxと同様の機能を実現することができます。
import React, { createContext, useContext, useState } from 'react';
const StateContext = createContext();
const StateProvider = ({ children }) => {
const [state, setState] = useState({ /* 初期状態 */ });
const value = { state, setState };
return (
<StateContext.Provider value={value}>
{children}
</StateContext.Provider>
);
};
const useAppState = () => {
const { state, setState } = useContext(StateContext);
return [state, setState];
};
export { StateProvider, useAppState };
このように、StateProvider
コンポーネントでuseState
フックを使って状態を管理し、useAppState
フックで状態を参照・更新することができます。コンポーネントツリーのどこからでもuseAppState
フックを使うことができるため、Reduxのようなグローバルな状態管理ができます。
2. useReducerフックを使う
useContext
フックを使った方法は、Reduxに似たAPIを提供することができますが、状態の更新に関するロジックを全て手動で実装する必要があります。useReducer
フックを使うことで、Reduxと同様のアクション・リデューサー・ディスパッチャーの考え方を取り入れた状態管理が可能になります。
import React, { createContext, useContext, useReducer } from 'react';
const StateContext = createContext();
const initialState = { /* 初期状態 */ };
const reducer = (state, action) => {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
throw new Error();
}
};
const StateProvider = ({ children }) => {
const [state, dispatch] = useReducer(reducer, initialState);
const value = { state, dispatch };
return (
<StateContext.Provider value={value}>
{children}
</StateContext.Provider>
);
};
const useAppState = () => {
const { state, dispatch } = useContext(StateContext);
const increment = () => dispatch({ type: 'increment' });
const decrement = () => dispatch({ type: 'decrement' });
return [state, { increment, decrement }];
};
export { StateProvider, useAppState };
このように、useReducer
フックを使って状態の更新に関するロジックを実装し、useAppState
フックでディスパッチャーを参照することができます。アクションに対するリデューサーの処理を行うことで、Reduxのような状態管理ができます。
まとめ
Reduxなどの状態管理ライブラリを使わずに、useContext
フックやuseReducer
フックを使って状態管理をすることができます。Reduxを導入することで得られる便利さもありますが、コードの複雑さや学習コストも考慮する必要があります。適切な状態管理方法を選択することで、効率的なフロントエンド開発が可能になります。