Redux の selector は、Redux ストア内の特定の状態(state)を取得するための関数です。selector を使うことで、コンポーネントは必要な状態だけを効率的に取得でき、不要な再レンダリングを防ぐことができます。
selector は単純に言うと、Redux ストアの状態から必要なデータを抽出する純粋関数です:
// 基本的な selector
const selectCounter = (state: RootState) => state.counter;
複雑な selector や最適化が必要な場合は、Redux エコシステムの一部である Reselect ライブラリがよく使われます:
import { createSelector } from 'reselect';
// 入力セレクタ
const selectItems = (state: RootState) => state.items;
const selectFilter = (state: RootState) => state.filter;
// メモ化されたセレクタ
const selectFilteredItems = createSelector(
[selectItems, selectFilter],
(items, filter) => items.filter(item => item.category === filter)
);
Redux Toolkit では、createSlice
で作成したスライスから自動的に selector を生成できます:
// counterSlice.ts
import { createSlice } from '@reduxjs/toolkit';
const counterSlice = createSlice({
name: 'counter',
initialState: { value: 0 },
reducers: {
increment: state => { state.value += 1 },
decrement: state => { state.value -= 1 }
}
});
// セレクタ
export const selectCount = (state: RootState) => state.counter.value;
export const { increment, decrement } = counterSlice.actions;
export default counterSlice.reducer;
import { useSelector, useDispatch } from 'react-redux';
import { selectCount, increment } from './counterSlice';
type CounterProps = {
label: string;
};
const Counter = ({ label }: CounterProps) => {
// useSelector でセレクタを使用
const count = useSelector(selectCount);
const dispatch = useDispatch();
return (
<div>
<h2>{label}: {count}</h2>
<button onClick={() => dispatch(increment())}>+</button>
</div>
);
};
このように selector を使うことで、コンポーネントは必要なデータだけを効率的に取得でき、Redux ストアの構造変更にも柔軟に対応できます。