メインコンテンツまでスキップ

5. State

Reactの状態管理

Reactの状態管理は、アプリケーションの状態を効率的に管理し、コンポーネントの再レンダリングを制御するための重要なコンセプトです。状態管理の方法には、ローカルステート、コンテキストAPI、および外部ライブラリを使用する方法があります。

Context API

ReactのContext APIは、グローバルな状態をコンポーネントツリー全体で共有するための手段を提供します。これにより、Propsの「ドリリング」を回避できます。

使用例

以下は、テーマを管理するためにContext APIを使用する例です:

import React, { createContext, useContext, useState } from 'react';

// コンテキストの作成
const ThemeContext = createContext();

function ThemeProvider({ children }) {
const [theme, setTheme] = useState('light');

return (
<ThemeContext.Provider value={{ theme, setTheme }}>
{children}
</ThemeContext.Provider>
);
}

function ThemeSwitcher() {
const { theme, setTheme } = useContext(ThemeContext);

return (
<button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
Switch to {theme === 'light' ? 'dark' : 'light'} mode
</button>
);
}

function App() {
return (
<ThemeProvider>
<ThemeSwitcher />
</ThemeProvider>
);
}

useReducer

useReducerフックは、より複雑な状態ロジックを管理するための方法を提供します。特に、状態が複数の値に依存する場合や、複雑な操作が必要な場合に有用です。

使用例

以下は、カウンターを管理するためにuseReducerを使用する例です:

import React, { useReducer } from 'react';

const initialState = { count: 0 };

function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
throw new Error();
}
}

function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);

return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
<button onClick={() => dispatch({ type: 'decrement' })}>-</button>
</div>
);
}

外部ライブラリ

より大規模なアプリケーションでは、状態管理を簡素化し、スケーラビリティを向上させるために外部ライブラリを使用することが一般的です。以下に代表的な状態管理ライブラリを紹介します。

Redux

Reduxは、予測可能な状態管理を提供するためのライブラリです。単一のグローバルな状態ツリーを持ち、アクションとリデューサーを通じて状態を変更します。

使用例

以下は、基本的なReduxの使用例です:

import React from 'react';
import { createStore } from 'redux';
import { Provider, useDispatch, useSelector } from 'react-redux';

// アクションタイプ
const INCREMENT = 'INCREMENT';
const DECREMENT = 'DECREMENT';

// アクションクリエーター
const increment = () => ({ type: INCREMENT });
const decrement = () => ({ type: DECREMENT });

// リデューサー
function counterReducer(state = { count: 0 }, action) {
switch (action.type) {
case INCREMENT:
return { count: state.count + 1 };
case DECREMENT:
return { count: state.count - 1 };
default:
return state;
}
}

// ストアの作成
const store = createStore(counterReducer);

function Counter() {
const count = useSelector((state) => state.count);
const dispatch = useDispatch();

return (
<div>
<p>Count: {count}</p>
<button onClick={() => dispatch(increment())}>+</button>
<button onClick={() => dispatch(decrement())}>-</button>
</div>
);
}

function App() {
return (
<Provider store={store}>
<Counter />
</Provider>
);
}

Recoil

Recoilは、Facebookが開発した状態管理ライブラリで、Reactのコンポーネントツリーに密接に統合されています。アトムとセレクターを使用して状態を管理します。

使用例

以下は、基本的なRecoilの使用例です:

import React from 'react';
import { RecoilRoot, atom, useRecoilState } from 'recoil';

// アトムの定義
const countState = atom({
key: 'countState', // 一意のキー
default: 0, // 初期状態
});

function Counter() {
const [count, setCount] = useRecoilState(countState);

return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>+</button>
<button onClick={() => setCount(count - 1)}>-</button>
</div>
);
}

function App() {
return (
<RecoilRoot>
<Counter />
</RecoilRoot>
);
}

Zustand

Zustandは、シンプルで直感的なAPIを持つ軽量な状態管理ライブラリです。Reactコンポーネントから直接状態を管理することができます。

使用例

以下は、基本的なZustandの使用例です:

import create from 'zustand';

// ストアの作成
const useStore = create((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
decrement: () => set((state) => ({ count: state.count - 1 })),
}));

function Counter() {
const count = useStore((state) => state.count);
const increment = useStore((state) => state.increment);
const decrement = useStore((state) => state.decrement);

return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>+</button>
<button onClick={decrement}>-</button>
</div>
);
}

function App() {
return <Counter />;
}

このように進めていきます。他に追加や修正の希望があればお知らせください。