React Redux Bindings
React Redux is the official set of React bindings for the Redux state management library. It provides utilities and hooks like `Provider`, `useSelector`, `useDispatch`, and `connect` to integrate Redux stores with React components efficiently. The current stable version is 9.2.0, which includes compatibility for React 19. The package typically follows a release cadence that aligns with major React and Redux core updates, with bugfix and minor feature releases occurring regularly. Key differentiators include its official status, deep integration with the Redux ecosystem, and optimizations for performance in large-scale React applications, such as automatic batching of updates with React 18+.
Common errors
-
Uncaught Error: createContext only works in Client Components. Add the "use client" directive at the top of the file to use it. Or, use a different wrapper for your store.
cause Attempting to use `Provider` or other React Context-reliant components in a React Server Component (RSC) environment without the `'use client'` directive.fixAdd `'use client';` at the top of the file where your `Provider` and client-side logic resides. React Redux v9.0.0 explicitly throws on use in RSCs to indicate incompatibility. -
Error: `react-redux` requires a `store` to be passed to the `Provider` component. Either pass a `store` prop or provide one through context.
cause The `Provider` component was rendered without a `store` prop, or the store context was not properly set up in testing environments.fixEnsure your `Provider` component receives a `store` prop: `<Provider store={myReduxStore}>...</Provider>`. In tests, wrap components with a test `Provider` or mock `useSelector`/`useDispatch`. -
TypeError: Cannot read properties of undefined (reading 'getState') (often in relation to 'store')
cause This usually indicates that the Redux store object is `undefined` or `null` when React Redux attempts to access it, often due to an incorrectly initialized `Provider` or a problem in the store creation logic.fixVerify that your `createStore` or `configureStore` call successfully returns a valid store object and that this object is correctly passed to the `Provider`'s `store` prop. Check for typos or asynchronous initialization issues.
Warnings
- breaking React Redux v9.0.0 requires React 18+ and Redux 5.0+ (or Redux Toolkit 2.0+). Older versions of React or Redux are no longer supported.
- breaking The package's internal build outputs and module resolution have changed significantly in v9.0.0 for improved ESM/CJS compatibility. This might affect bundler configurations or direct file imports if you were relying on specific internal paths.
- gotcha Automatic batching of Redux updates is handled by React 18+. The `batch` utility from `react-redux` is still exported but is generally not needed unless you are performing updates outside of React's event system or need specific batching behavior.
- breaking The awkward peer dependency on `react-native` for `unstable_batchedUpdates` was removed in v9.1.2. React Native projects should now work more seamlessly, but specific `react-native` related bundling issues have been addressed in earlier 9.x patch releases.
- gotcha When using TypeScript, remember to pre-type your `useSelector` and `useDispatch` hooks to avoid needing to provide types at every call site. Version 9.1.0 introduced the `.withTypes` syntax for this.
Install
-
npm install react-redux -
yarn add react-redux -
pnpm add react-redux
Imports
- Provider
const { Provider } = require('react-redux');import { Provider } from 'react-redux'; - useSelector
import useSelector from 'react-redux';
import { useSelector } from 'react-redux'; - useDispatch
import useDispatch from 'react-redux';
import { useDispatch } from 'react-redux'; - connect
import connect from 'react-redux';
import { connect } from 'react-redux'; - batch
import { unstable_batchedUpdates } from 'react-dom';import { batch } from 'react-redux'; - TypedUseSelectorHook
import { TypedUseSelectorHook } from 'react-redux';import type { TypedUseSelectorHook } from 'react-redux';
Quickstart
import React from 'react';
import { createStore } from 'redux';
import { Provider, useSelector, useDispatch } from 'react-redux';
// Redux Store Setup
interface RootState { count: number; }
const initialState: RootState = { count: 0 };
function counterReducer(state = initialState, action: { type: string }) {
switch (action.type) {
case 'increment': return { count: state.count + 1 };
case 'decrement': return { count: state.count - 1 };
default: return state;
}
}
const store = createStore(counterReducer);
// React Component
function Counter() {
const count = useSelector((state: RootState) => state.count);
const dispatch = useDispatch();
return (
<div>
<h1>Count: {count}</h1>
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
<button onClick={() => dispatch({ type: 'decrement' })}>-</button>
</div>
);
}
// App Root
function App() {
return (
<Provider store={store}>
<Counter />
</Provider>
);
}
export default App;