Official React bindings for Redux state management with hooks and higher-order components
—
Modern React hooks for accessing Redux store state and dispatch functions with optimal performance and type safety.
Extracts data from Redux store state with automatic re-rendering when selected data changes. Uses shallow equality by default but supports custom equality functions.
/**
* Hook for extracting data from Redux store state
* @param selector - Function that receives state and returns selected data
* @param equalityFnOrOptions - Optional equality function or options object
* @returns Selected data from store state
*/
interface UseSelector<StateType = unknown> {
<TState extends StateType = StateType, Selected = unknown>(
selector: (state: TState) => Selected,
equalityFnOrOptions?: EqualityFn<Selected> | UseSelectorOptions<Selected>
): Selected;
withTypes: <OverrideStateType extends StateType>() => UseSelector<OverrideStateType>;
}
const useSelector: UseSelector;
interface UseSelectorOptions<Selected = unknown> {
equalityFn?: EqualityFn<Selected>;
devModeChecks?: Partial<DevModeChecks>;
}
type EqualityFn<T> = (a: T, b: T) => boolean;Usage Examples:
import { useSelector } from "react-redux";
// Basic usage
const todos = useSelector((state: RootState) => state.todos);
// With custom equality function
const todoCount = useSelector(
(state: RootState) => state.todos.length,
(prev, next) => prev === next
);
// With options object
const visibleTodos = useSelector(
(state: RootState) => state.todos.filter(todo => todo.visible),
{
equalityFn: (prev, next) => prev.length === next.length,
devModeChecks: { stabilityCheck: 'once' }
}
);
// Using pre-typed hook
const useAppSelector = useSelector.withTypes<RootState>();
const user = useAppSelector((state) => state.user); // Fully typedReturns the dispatch function from the Redux store, allowing components to dispatch actions.
/**
* Hook for accessing Redux store dispatch function
* @returns Dispatch function from the store
*/
interface UseDispatch<DispatchType extends Dispatch<UnknownAction> = Dispatch<UnknownAction>> {
<AppDispatch extends DispatchType = DispatchType>(): AppDispatch;
withTypes: <OverrideDispatchType extends DispatchType>() => UseDispatch<OverrideDispatchType>;
}
const useDispatch: UseDispatch;Usage Examples:
import { useDispatch } from "react-redux";
// Basic usage
const dispatch = useDispatch();
const handleAddTodo = (text: string) => {
dispatch({ type: "ADD_TODO", payload: text });
};
// With thunk actions
const handleAsyncAction = async () => {
dispatch(fetchUserData(userId));
};
// Using pre-typed hook
const useAppDispatch = useDispatch.withTypes<AppDispatch>();
const dispatch = useAppDispatch(); // Typed with thunk supportReturns the Redux store instance directly. Rarely needed as useSelector and useDispatch cover most use cases.
/**
* Hook for accessing Redux store instance
* @returns The Redux store instance
*/
interface UseStore<StoreType extends Store> {
(): StoreType;
<StateType extends ReturnType<StoreType['getState']> = ReturnType<StoreType['getState']>,
ActionType extends Action = ExtractStoreActionType<Store>>(): Store<StateType, ActionType>;
withTypes: <OverrideStoreType extends StoreType>() => UseStore<OverrideStoreType>;
}
const useStore: UseStore<Store>;
type ExtractStoreActionType<StoreType extends Store> =
StoreType extends Store<any, infer ActionType> ? ActionType : never;Usage Examples:
import { useStore } from "react-redux";
// Basic usage
const store = useStore();
// Access current state directly
const currentState = store.getState();
// Subscribe to store changes (not recommended, use useSelector instead)
useEffect(() => {
const unsubscribe = store.subscribe(() => {
console.log("Store updated:", store.getState());
});
return unsubscribe;
}, [store]);
// Using pre-typed hook
const useAppStore = useStore.withTypes<AppStore>();
const store = useAppStore(); // Fully typed storeCreate custom hooks that use a different React context, useful for multiple store scenarios.
/**
* Creates a custom useSelector hook for a specific context
* @param context - React context to use instead of default ReactReduxContext
* @returns Custom useSelector hook bound to the context
*/
function createSelectorHook<StateType = unknown>(
context?: Context<ReactReduxContextValue<StateType> | null>
): UseSelector<StateType>;
/**
* Creates a custom useDispatch hook for a specific context
* @param context - React context to use instead of default ReactReduxContext
* @returns Custom useDispatch hook bound to the context
*/
function createDispatchHook<StateType = unknown, ActionType extends Action = UnknownAction>(
context?: Context<ReactReduxContextValue<StateType, ActionType> | null>
): UseDispatch<Dispatch<ActionType>>;
/**
* Creates a custom useStore hook for a specific context
* @param context - React context to use instead of default ReactReduxContext
* @returns Custom useStore hook bound to the context
*/
function createStoreHook<StateType = unknown, ActionType extends Action = Action>(
context?: Context<ReactReduxContextValue<StateType, ActionType> | null>
): UseStore<Store<StateType, ActionType>>;Usage Examples:
import { createContext } from "react";
import { createSelectorHook, createDispatchHook, createStoreHook } from "react-redux";
// Create custom context for second store
const SecondaryContext = createContext(null);
// Create custom hooks
const useSecondarySelector = createSelectorHook(SecondaryContext);
const useSecondaryDispatch = createDispatchHook(SecondaryContext);
const useSecondaryStore = createStoreHook(SecondaryContext);
// Use in components
function ComponentWithSecondaryStore() {
const data = useSecondarySelector((state) => state.data);
const dispatch = useSecondaryDispatch();
const store = useSecondaryStore();
return <div>{data}</div>;
}
// Create pre-typed custom hooks with withTypes()
const useSecondaryAppSelector = useSecondarySelector.withTypes<SecondaryRootState>();
const useSecondaryAppDispatch = useSecondaryDispatch.withTypes<SecondaryAppDispatch>();React Redux includes built-in development checks to help identify common issues:
type DevModeCheckFrequency = 'never' | 'once' | 'always';
interface DevModeChecks {
stabilityCheck: DevModeCheckFrequency;
identityFunctionCheck: DevModeCheckFrequency;
}'never': Disable the check'once': Run check only once per selector'always': Run check on every selector callConfiguration:
// Configure checks in Provider
<Provider
store={store}
stabilityCheck="once"
identityFunctionCheck="always"
>
<App />
</Provider>
// Configure checks per selector
const data = useSelector(
(state) => state.data,
{ devModeChecks: { stabilityCheck: 'never' } }
);React Redux 9.1.0+ supports pre-typed hooks for better TypeScript developer experience:
// Define your app types
type RootState = ReturnType<typeof store.getState>;
type AppDispatch = typeof store.dispatch;
type AppStore = typeof store;
// Create pre-typed hooks
export const useAppSelector = useSelector.withTypes<RootState>();
export const useAppDispatch = useDispatch.withTypes<AppDispatch>();
export const useAppStore = useStore.withTypes<AppStore>();
// Use throughout your app with full type safety
const todos = useAppSelector((state) => state.todos); // state is typed as RootState
const dispatch = useAppDispatch(); // dispatch is typed as AppDispatchInstall with Tessl CLI
npx tessl i tessl/npm-react-redux