Professional Documents
Culture Documents
Getting Started
Tutorials
Quick Start
API Reference
Provider
Hooks
connect()
batch()
Guides
Troubleshooting
Getting Started with React Redux
React Redux is the ofcial React UI bindings layer for Redux. It lets your React components read data from a Redux
store, and dispatch actions to the store to update state.
Installation
React Redux 8.x requires React 16.8.3 or later / React Native 0.59 or later, in order to make use of React Hooks.
The recommended way to start new apps with React and Redux is by using the ofcial Redux+JS template or Redux+TS
template for Create React App, which takes advantage of Redux Toolkit and React Redux's integration with React
components.
You'll also need to install Redux and set up a Redux store in your app.
API Overview
Provider
React Redux includes a <Provider /> component, which makes the Redux store available to the rest of your app:
// As of React 18
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
<Provider store={store}>
<App />
</Provider>
)
Hooks
React Redux provides a pair of custom React hooks that allow your React components to interact with the Redux
store.
useSelector reads a value from the store state and subscribes to updates, while useDispatch returns the store's
return (
<div>
<div className={styles.row}>
<button
className={styles.button}
aria-label="Increment value"
onClick={() => dispatch(increment())}
>
+
</button>
<span className={styles.value}>{count}</span>
<button
className={styles.button}
aria-label="Decrement value"
onClick={() => dispatch(decrement())}
>
-
</button>
</div>
{/* omit additional rendering output here */}
</div>
)
}
Redux maintainer Mark Erikson appeared on the "Learn with Jason" show to explain how we recommend using Redux
today. The show includes a live-coded example app that shows how to use Redux Toolkit and React-Redux hooks with
Typescript, as well as the new RTK Query data fetching APIs.
See the "Learn Modern Redux" show notes page for a transcript and links to the example app source.
The #redux channel of the Reactifux Discord community is our ofcial resource for all questions related to
learning and using Redux. Reactifux is a great place to hang out, ask questions, and learn - come join us!
You can also ask questions on Stack Overfow using the #redux tag.
Docs Translations
Portuguese
Why Use React Redux?
Redux itself is a standalone library that can be used with any UI layer or framework, including React, Angular, Vue,
Ember, and vanilla JS. Although Redux and React are commonly used together, they are independent of each other.
If you are using Redux with any kind of UI framework, you will normally use a "UI binding" library to tie Redux
together with your UI framework, rather than directly interacting with the store from your UI code.
React Redux is the ofcial Redux UI binding library for React. If you are using Redux and React together, you
should also use React Redux to bind these two libraries.
To understand why you should use React Redux, it may help to understand what a "UI binding library" does.
INFO
If you have questions about whether you should use Redux in general, please see these articles for discussion of
when and why you might want to use Redux, and how it's intended to be used:
Using Redux with any UI layer requires the same consistent set of steps:
While it is possible to write this logic by hand, doing so would become very repetitive. In addition, optimizing UI
performance would require complicated logic.
The process of subscribing to the store, checking for updated data, and triggering a re-render can be made more
generic and reusable. A UI binding library like React Redux handles the store interaction logic, so you don't
have to write that code yourself.
INFO
For a deeper look at how React Redux works internally and how it handles the store interaction for you, see Idiomatic
Redux: The History and Implementation of React Redux.
While Redux can be used with any UI layer, it was originally designed and intended for use with React. There are UI
binding layers for many other frameworks, but React Redux is maintained directly by the Redux team.
As the ofcial Redux binding for React, React Redux is kept up-to-date with any API changes from either library, to
ensure that your React components behave as expected. Its intended usage adopts the design principles of React -
writing declarative components.
React is generally fast, but by default any updates to a component will cause React to re-render all of the components
inside that part of the component tree. This does require work, and if the data for a given component hasn't changed,
then re-rendering is likely some wasted effort because the requested UI output would be the same.
If performance is a concern, the best way to improve performance is to skip unnecessary re-renders, so that
components only re-render when their data has actually changed. React Redux implements many performance
optimizations internally, so that your own component only re-renders when it actually needs to.
In addition, by connecting multiple components in your React component tree, you can ensure that each connected
component only extracts the specifc pieces of data from the store state that are needed by that component. This
means that your own component will need to re-render less often, because most of the time those specifc pieces of
data haven't changed.
Community Support
As the ofcial binding library for React and Redux, React Redux has a large community of users. This makes it easier to
ask for help, learn about best practices, use libraries that build on top of React Redux, and reuse your knowledge
across different applications.
Community Resources
PREREQUISITES
Introduction
Welcome to the React Redux Quick Start tutorial! This tutorial will briefy introduce you to React Redux and teach
you how to start using it correctly.
This page will focus on just how to set up a Redux application with Redux Toolkit and the main APIs you'll use. For
explanations of what Redux is, how it works, and full examples of how to use Redux Toolkit, see the Redux core docs
tutorials.
For this tutorial, we assume that you're using Redux Toolkit and React Redux together, as that is the standard Redux
usage pattern. The examples are based on a typical Create-React-App folder structure where all the application code
is in a src, but the patterns can be adapted to whatever project or folder setup you're using.
The Redux+JS template for Create-React-App comes with this same project setup already confgured.
Usage Summary
Add the Redux Toolkit and React Redux packages to your project:
Create a fle named src/app/store.js. Import the configureStore API from Redux Toolkit. We'll start by creating an
empty Redux store, and exporting it:
app/store.js
import { configureStore } from '@reduxjs/toolkit'
This creates a Redux store, and also automatically confgure the Redux DevTools extension so that you can inspect the
store while developing.
Once the store is created, we can make it available to our React components by putting a React Redux <Provider>
around our application in src/index.js. Import the Redux store we just created, put a <Provider> around your <App>,
and pass the store as a prop:
index.js
import React from 'react'
import ReactDOM from 'react-dom/client'
import './index.css'
import App from './App'
import store from './app/store'
import { Provider } from 'react-redux'
// As of React 18
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
<Provider store={store}>
<App />
</Provider>
)
Add a new fle named src/features/counter/counterSlice.js. In that fle, import the createSlice API from Redux
Toolkit.
Creating a slice requires a string name to identify the slice, an initial state value, and one or more reducer functions to
defne how the state can be updated. Once a slice is created, we can export the generated Redux action creators and
the reducer function for the whole slice.
Redux requires that we write all state updates immutably, by making copies of data and updating the copies.
However, Redux Toolkit's createSlice and createReducer APIs use Immer inside to allow us to write "mutating"
update logic that becomes correct immutable updates.
features/counter/counterSlice.js
import { createSlice } from '@reduxjs/toolkit'
Next, we need to import the reducer function from the counter slice and add it to our store. By defning a feld inside
the reducers parameter, we tell the store to use this slice reducer function to handle all updates to that state.
app/store.js
import { configureStore } from '@reduxjs/toolkit'
import counterReducer from '../features/counter/counterSlice'
export default configureStore({
reducer: {
counter: counterReducer,
},
})
Now we can use the React Redux hooks to let React components interact with the Redux store. We can read data from
the store with useSelector, and dispatch actions using useDispatch. Create a src/features/counter/Counter.js fle
with a <Counter> component inside, then import that component into App.js and render it inside of <App>.
features/counter/Counter.js
import React from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { decrement, increment } from './counterSlice'
import styles from './Counter.module.css'
return (
<div>
<div>
<button
aria-label="Increment value"
onClick={() => dispatch(increment())}
>
Increment
</button>
<span>{count}</span>
<button
aria-label="Decrement value"
onClick={() => dispatch(decrement())}
>
Decrement
</button>
</div>
</div>
)
}
Now, any time you click the "Increment" and "Decrement buttons:
That was a brief overview of how to set up and use Redux Toolkit with React. Recapping the details:
SUMMARY
We recommend going through the "Redux Essentials" and "Redux Fundamentals" tutorials in the Redux core
docs, which will give you a complete understanding of how Redux works, what Redux Toolkit and React Redux do, and
how to use it correctly.
React Redux TypeScript Quick Start
How to set up and use Redux Toolkit and React Redux with TypeScript
PREREQUISITES
Introduction
Welcome to the React Redux TypeScript Quick Start tutorial! This tutorial will briefy show how to use TypeScript
with Redux Toolkit.
This page focuses on just how to set up the TypeScript aspects . For explanations of what Redux is, how it works, and
full examples of how to use Redux, see the Redux core docs tutorials.
Both React-Redux and Redux Toolkit are already written in TypeScript, so their TS type defnitions are built in.
React Redux has its type defnitions in a separate @types/react-redux typedefs package on NPM. In addition to typing
the library functions, the types also export some helpers to make it easier to write typesafe interfaces between your
Redux store and your React components.
The Redux+TS template for Create-React-App comes with a working example of these patterns already confgured.
INFO
The recently updated @types/react@18 major version has changed component defnitions to remove having children
as a prop by default. This causes errors if you have multiple copies of @types/react in your project. To fx this, tell your
package manager to resolve @types/react to a single version. Details:
https://github.com/facebook/react/issues/24304#issuecomment-1094565891
Project Setup
Defne Root State and Dispatch Types
Redux Toolkit's configureStore API should not need any additional typings. You will, however, want to extract the
RootState type and the Dispatch type so that they can be referenced as needed. Inferring these types from the store
itself means that they correctly update as you add more state slices or modify middleware settings.
Since those are types, it's safe to export them directly from your store setup fle such as app/store.ts and import
them directly into other fles.
app/store.ts
import { configureStore } from '@reduxjs/toolkit'
// ...
// Infer the `RootState` and `AppDispatch` types from the store itself
export type RootState = ReturnType<typeof store.getState>
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch
While it's possible to import the RootState and AppDispatch types into each component, it's better to create typed
versions of the useDispatch and useSelector hooks for usage in your application. . This is important for a couple
reasons:
For useSelector, it saves you the need to type (state: RootState) every time
For useDispatch, the default Dispatch type does not know about thunks. In order to correctly dispatch thunks,
you need to use the specifc customized AppDispatch type from the store that includes the thunk middleware
types, and use that with useDispatch. Adding a pre-typed useDispatch hook keeps you from forgetting to import
AppDispatch where it's needed.
Since these are actual variables, not types, it's important to defne them in a separate fle such as app/hooks.ts, not
the store setup fle. This allows you to import them into any component fle that needs to use the hooks, and avoids
potential circular import dependency issues.
app/hooks.ts
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'
import type { RootState, AppDispatch } from './store'
Application Usage
Each slice fle should defne a type for its initial state value, so that createSlice can correctly infer the type of state in
each case reducer.
All generated actions should be defned using the PayloadAction<T> type from Redux Toolkit, which takes the type of
the action.payload feld as its generic argument.
You can safely import the RootState type from the store fle here. It's a circular import, but the TypeScript compiler
can correctly handle that for types. This may be needed for use cases like writing selector functions.
features/counter/counterSlice.ts
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
import type { RootState } from '../../app/store'
// Other code such as selectors can use the imported `RootState` type
export const selectCount = (state: RootState) => state.counter.value
The generated action creators will be correctly typed to accept a payload argument based on the PayloadAction<T>
type you provided for the reducer. For example, incrementByAmount requires a number as its argument.
In some cases, TypeScript may unnecessarily tighten the type of the initial state. If that happens, you can work around
it by casting the initial state using as, instead of declaring the type of the variable:
In component fles, import the pre-typed hooks instead of the standard hooks from React-Redux.
features/counter/Counter.tsx
import React, { useState } from 'react'
What's Next?
See the "Usage with TypeScript" page for extended details on how to use Redux Toolkit's APIs with TypeScript.
Tutorial: Using the connect API
TIP
We now recommend using the React-Redux hooks API as the default. However, the connect API still works fne.
This tutorial also shows some older practices we no longer recommend, like separating Redux logic into folders by
type. We've kept this tutorial as-is for completeness, but recommend reading through the "Redux Essentials" tutorial
and the Redux Style Guide in the Redux docs for our current best practices.
We're working on a new tutorial that will introduce the hooks APIs. Until then, we suggest reading Redux
Fundamentals, Part 5: UI and React for a hooks tutorial.
To see how to use React Redux in practice, we’ll show a step-by-step example by creating a todo list app.
Jump to
TodoApp is the entry component for our app. It renders the header, the AddTodo, TodoList, and
VisibilityFilters components.
AddTodo is the component that allows a user to input a todo item and add to the list upon clicking its “Add Todo”
button:
It renders the fltered list of todos when one of the VisibilityFilters is selected.
Todo is the component that renders a single todo item:
It renders the todo content, and shows that a todo is completed by crossing it out.
It dispatches the action to toggle the todo's complete status upon onClick.
VisibilityFilters renders a simple set of flters: all, completed, and incomplete. Clicking on each one of them
flters the todos:
It accepts an activeFilter prop from the parent that indicates which flter is currently selected by the user.
An active flter is rendered with an underscore.
The Redux portion of the application has been set up using the patterns recommended in the Redux docs:
Store
todos: A normalized reducer of todos. It contains a byIds map of all todos and a allIds that contains the
list of all ids.
Action Creators
addTodo creates the action to add todos. It takes a single string variable content and returns an ADD_TODO
setFilter creates the action to set the app’s active flter. It takes a single string variable filter and returns
Toggles the completed feld for the todo upon receiving the TOGGLE_TODO action
The visibilityFilters reducer sets its slice of store to the new flter it receives from the SET_FILTER action
payload
Action Types
We use a fle actionTypes.js to hold the constants of action types to be reused
Selectors
getTodoList returns the allIds list from the todos store
getTodos is slightly more complex. It takes all the ids from allIds, fnds each todo in byIds, and returns the
fnal array of todos
You may check out this CodeSandbox for the source code of the UI components and the unconnected Redux store
described above.
We will now show how to connect this store to our app using React Redux.
First we need to make the store available to our app. To do this, we wrap our app with the <Provider /> API provided
by React Redux.
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
import TodoApp from './TodoApp'
// As of React 18
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
<Provider store={store}>
<TodoApp />
</Provider>
)
Notice how our <TodoApp /> is now wrapped with the <Provider /> with store passed in as a prop.
Connecting the Components
React Redux provides a connect function for you to read values from the Redux store (and re-read the values when
the store updates).
mapStateToProps: called every time the store state changes. It receives the entire store state, and should return
an object of data this component needs.
mapDispatchToProps: this parameter can either be a function, or an object.
If it’s a function, it will be called once on component creation. It will receive dispatch as an argument, and
should return an object full of functions that use dispatch to dispatch actions.
If it’s an object full of action creators, each action creator will be turned into a prop function that
automatically dispatches its action when called. Note: We recommend using this “object shorthand” form.
const mapDispatchToProps = {
// ... normally is an object full of action creators
}
Let’s work on <AddTodo /> frst. It needs to trigger changes to the store to add new todos. Therefore, it needs to be
able to dispatch actions to the store. Here’s how we do it.
// redux/actions.js
import { ADD_TODO } from './actionTypes'
let nextTodoId = 0
export const addTodo = (content) => ({
type: ADD_TODO,
payload: {
id: ++nextTodoId,
content,
},
})
By passing it to connect, our component receives it as a prop, and it will automatically dispatch the action when it’s
called.
// components/AddTodo.js
Notice now that <AddTodo /> is wrapped with a parent component called <Connect(AddTodo) />. Meanwhile, <AddTodo
/> now gains one prop: the addTodo action.
We also need to implement the handleAddTodo function to let it dispatch the addTodo action and reset the input
// components/AddTodo.js
handleAddTodo = () => {
// dispatches actions to add todo
this.props.addTodo(this.state.input)
render() {
return (
<div>
<input
onChange={(e) => this.updateInput(e.target.value)}
value={this.state.input}
/>
<button className="add-todo" onClick={this.handleAddTodo}>
Add Todo
</button>
</div>
)
}
}
Now our <AddTodo /> is connected to the store. When we add a todo it would dispatch an action to change the store.
We are not seeing it in the app because the other components are not connected yet. If you have the Redux DevTools
Extension hooked up, you should see the action being dispatched:
You should also see that the store has changed accordingly:
The <TodoList /> component is responsible for rendering the list of todos. Therefore, it needs to read data from the
store. We enable it by calling connect with the mapStateToProps parameter, a function describing which part of the
data we need from the store.
Our <Todo /> component takes the todo item as props. We have this information from the byIds feld of the todos.
However, we also need the information from the allIds feld of the store indicating which todos and in what order
they should be rendered. Our mapStateToProps function may look like this:
// components/TodoList.js
// ...other imports
import { connect } from "react-redux";
Luckily we have a selector that does exactly this. We may simply import the selector and use it here.
// redux/selectors.js
// ...other imports
import { connect } from "react-redux";
import { getTodos } from "../redux/selectors";
We recommend encapsulating any complex lookups or computations of data in selector functions. In addition, you
can further optimize the performance by using Reselect to write “memoized” selectors that can skip unnecessary
work. (See the Redux docs page on Computing Derived Data and the blog post Idiomatic Redux: Using Reselect
Selectors for Encapsulation and Performance for more information on why and how to use selector functions.)
Now that our <TodoList /> is connected to the store. It should receive the list of todos, map over them, and pass each
todo to the <Todo /> component. <Todo /> will in turn render them to the screen. Now try adding a todo. It should
come up on our todo list!
We will connect more components. Before we do this, let’s pause and learn a bit more about connect frst.
Depending on what kind of components you are working with, there are different ways of calling connect , with the
most common ones summarized as below:
If you call connect without providing any arguments, your component will:
// ... Component
export default connect()(Component) // Component will receive `dispatch` (just like our <TodoList />!)
subscribe to the values that mapStateToProps extracts from the store, and re-render only when those values have
changed
// ... Component
const mapStateToProps = (state) => state.partOfState
export default connect(mapStateToProps)(Component)
If you call connect with both mapStateToProps and mapDispatchToProps, your component will:
subscribe to the values that mapStateToProps extracts from the store, and re-render only when those values have
changed
receive all of the action creators you inject with mapDispatchToProps as props and automatically dispatch the
actions upon being called.
These four cases cover the most basic usages of connect. To read more about connect, continue reading our API
section that explains it in more detail.
How should we implement the interaction of toggling todos? A keen reader might already have an answer. If you
have your environment set up and have followed through up until this point, now is a good time to leave it aside and
implement the feature by yourself. There would be no surprise that we connect our <Todo /> to dispatch toggleTodo
in a similar way:
// components/Todo.js
The <VisibilityFilters /> component needs to be able to read from the store which flter is currently active, and
dispatch actions to the store. Therefore, we need to pass both a mapStateToProps and mapDispatchToProps. The
mapStateToProps here can be a simple accessor of the visibilityFilter state. And the mapDispatchToProps will
// components/VisibilityFilters.js
Meanwhile, we also need to update our <TodoList /> component to flter todos according to the active flter.
Previously the mapStateToProps we passed to the <TodoList /> connect function call was simply the selector that
selects the whole list of todos. Let’s write another selector to help fltering todos by their status.
// redux/selectors.js
// components/TodoList.js
// ...
Now we've fnished a very simple example of a todo app with React Redux. All our components are connected! Isn't
that nice?
Links
As of React-Redux v8, React-Redux is fully written in TypeScript, and the types are included in the published package.
The types also export some helpers to make it easier to write typesafe interfaces between your Redux store and your
React components.
INFO
The recently updated @types/react@18 major version has changed component defnitions to remove having children
as a prop by default. This causes errors if you have multiple copies of @types/react in your project. To fx this, tell your
package manager to resolve @types/react to a single version. Details:
https://github.com/facebook/react/issues/24304#issuecomment-1094565891
We assume that a typical Redux project is using Redux Toolkit and React Redux together.
Redux Toolkit (RTK) is the standard approach for writing modern Redux logic. RTK is already written in TypeScript, and
its API is designed to provide a good experience for TypeScript usage.
The Redux+TS template for Create-React-App comes with a working example of these patterns already confgured.
Using confgureStore should not need any additional typings. You will, however, want to extract the RootState type
and the Dispatch type so that they can be referenced as needed. Inferring these types from the store itself means
that they correctly update as you add more state slices or modify middleware settings.
Since those are types, it's safe to export them directly from your store setup fle such as app/store.ts and import
them directly into other fles.
app/store.ts
import { configureStore } from '@reduxjs/toolkit'
// ...
// Infer the `RootState` and `AppDispatch` types from the store itself
export type RootState = ReturnType<typeof store.getState>
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch
While it's possible to import the RootState and AppDispatch types into each component, it's better to create pre-
typed versions of the useDispatch and useSelector hooks for usage in your application. This is important for a
couple reasons:
For useSelector, it saves you the need to type (state: RootState) every time
For useDispatch, the default Dispatch type does not know about thunks or other middleware. In order to
correctly dispatch thunks, you need to use the specifc customized AppDispatch type from the store that includes
the thunk middleware types, and use that with useDispatch. Adding a pre-typed useDispatch hook keeps you
from forgetting to import AppDispatch where it's needed.
Since these are actual variables, not types, it's important to defne them in a separate fle such as app/hooks.ts, not
the store setup fle. This allows you to import them into any component fle that needs to use the hooks, and avoids
potential circular import dependency issues.
app/hooks.ts
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'
import type { RootState, AppDispatch } from './store'
We recommend using the pre-typed useAppSelector and useAppDispatch hooks shown above. If you prefer not to use
those, here is how to type the hooks by themselves.
When writing selector functions for use with useSelector, you should explicitly defne the type of the state
parameter. TS should be able to then infer the return type of the selector, which will be reused as the return type of
interface RootState {
isOn: boolean
}
By default, the return value of useDispatch is the standard Dispatch type defned by the Redux core types, so no
declarations are needed:
If you have a customized version of the Dispatch type, you may use that type explicitly:
// store.ts
export type AppDispatch = typeof store.dispatch
// MyComponent.tsx
const dispatch: AppDispatch = useDispatch()
connect consists of two functions that are called sequentially. The frst function accepts mapState and mapDispatch as
arguments, and returns a second function. The second function accepts the component to be wrapped, and returns a
new wrapper component that passes down the props from mapState and mapDispatch. Normally, both functions are
called together, like connect(mapState, mapDispatch)(MyComponent).
The package includes a helper type, ConnectedProps, that can extract the return types of mapStateToProps and
mapDispatchToProps from the frst function. This means that if you split the connect call into two steps, all of the
"props from Redux" can be inferred automatically without having to write them by hand. While this approach may
feel unusual if you've been using React-Redux for a while, it does simplify the type declarations considerably.
interface RootState {
isOn: boolean
}
const mapDispatch = {
toggleOn: () => ({ type: 'TOGGLE_IS_ON' }),
}
The return type of ConnectedProps can then be used to type your props object.
Because types can be defned in any order, you can still declare your component before declaring the connector if you
want.
The connect higher-order component is somewhat complex to type, because there are 3 sources of props:
mapStateToProps, mapDispatchToProps, and props passed in from the parent component. Here's a full example of
what it looks like to do that manually.
interface StateProps {
isOn: boolean
}
interface DispatchProps {
toggleOn: () => void
}
interface OwnProps {
backgroundColor: string
}
const mapDispatch = {
toggleOn: () => ({ type: 'TOGGLE_IS_ON' }),
}
It is also possible to shorten this somewhat, by inferring the types of mapState and mapDispatch:
const mapDispatch = {
toggleOn: () => ({ type: 'TOGGLE_IS_ON' }),
}
However, inferring the type of mapDispatch this way will break if it is defned as an object and also refers to thunks.
Recommendations
The hooks API is generally simpler to use with static types. If you're looking for the easiest solution for using static
types with React-Redux, use the hooks API.
If you're using connect, we recommend using the ConnectedProps<T> approach for inferring the props from
Redux, as that requires the fewest explicit type declarations.
Resources
Redux docs: Usage with TypeScript: Examples of how to use Redux Toolkit, the Redux core, and React Redux with
TypeScript
Redux Toolkit docs: TypeScript Quick start: shows how to use RTK and the React-Redux hooks API with
TypeScript
As the frst argument passed in to connect, mapStateToProps is used for selecting the part of the data from the store
that the connected component needs. It’s frequently referred to as just mapState for short.
Defning mapStateToProps
It should take a frst argument called state, optionally a second argument called ownProps, and return a plain object
containing the data that the connected component needs.
This function should be passed as the frst argument to connect, and will be called every time when the Redux store
state changes. If you do not wish to subscribe to the store, pass null or undefined to connect in place of
mapStateToProps.
It does not matter if a mapStateToProps function is written using the function keyword (function
mapState(state) { } ) or as an arrow function (const mapState = (state) => { } ) - it will work the same either
way.
Arguments
1. state
2. ownProps (optional)
state
The frst argument to a mapStateToProps function is the entire Redux store state (the same value returned by a call to
store.getState()). Because of this, the frst argument is traditionally just called state. (While you can give the
argument any name you want, calling it store would be incorrect - it's the "state value", not the "store instance".)
The mapStateToProps function should always be written with at least state passed in.
// TodoList.js
function mapStateToProps(state) {
const { todos } = state
return { todoList: todos.allIds }
}
ownProps (optional)
You may defne the function with a second argument, ownProps, if your component needs the data from its own props
to retrieve data from the store. This argument will contain all of the props given to the wrapper component that was
generated by connect.
// Todo.js
You do not need to include values from ownProps in the object returned from mapStateToProps. connect will
automatically merge those different prop sources into a fnal set of props.
Return
Your mapStateToProps function should return a plain object that contains the data the component needs:
Each feld in the object will become a prop for your actual component
The values in the felds will be used to determine if your component needs to re-render
For example:
function mapStateToProps(state) {
return {
a: 42,
todos: state.todos,
filter: state.visibilityFilter,
}
}
Note: In advanced scenarios where you need more control over the rendering performance,
mapStateToProps can also return a function. In this case, that function will be used as the fnal
mapStateToProps for a particular component instance. This allows you to do per-instance memoization. See
the Advanced Usage: Factory Functions section of the docs for more details, as well as PR #279 and the
tests it adds. Most apps never need this.
Usage Guidelines
mapStateToProps functions can, and should, do a lot more than just return state.someSlice. They have the
responsibility of "re-shaping" store data as needed for that component. This may include returning a value as a
specifc prop name, combining pieces of data from different parts of the state tree, and transforming the store data in
different ways.
We highly encourage the use of "selector" functions to help encapsulate the process of extracting values from specifc
locations in the state tree. Memoized selector functions also play a key role in improving application performance (see
the following sections in this page and the Advanced Usage: Computing Derived Data page for more details on why
and how to use selectors.)
Whenever the store changes, all of the mapStateToProps functions of all of the connected components will run.
Because of this, your mapStateToProps functions should run as fast as possible. This also means that a slow
mapStateToProps function can be a potential bottleneck for your application.
As part of the "re-shaping data" idea, mapStateToProps functions frequently need to transform data in various ways
(such as fltering an array, mapping an array of IDs to their corresponding objects, or extracting plain JS values from
Immutable.js objects). These transformations can often be expensive, both in terms of cost to execute the
transformation, and whether the component re-renders as a result. If performance is a concern, ensure that these
transformations are only run if the input values have changed.
Much like a Redux reducer, a mapStateToProps function should always be 100% pure and synchronous. It should only
take state (and ownProps) as arguments, and return the data the component needs as props without mutating those
arguments. It should not be used to trigger asynchronous behavior like AJAX calls for data fetching, and the functions
should not be declared as async.
React Redux internally implements the shouldComponentUpdate method such that the wrapper component re-renders
precisely when the data your component needs has changed. By default, React Redux decides whether the contents
of the object returned from mapStateToProps are different using === comparison (a "shallow equality" check) on each
felds of the returned object. If any of the felds have changed, then your component will be re-rendered so it can
receive the updated values as props. Note that returning a mutated object of the same reference is a common
mistake that can result in your component not re-rendering when expected.
To summarize the behavior of the component wrapped by connect with mapStateToProps to extract data from the
store:
React Redux does shallow comparisons to see if the mapStateToProps results have changed. It’s easy to accidentally
return new object or array references every time, which would cause your component to re-render even if the data is
actually the same.
Many common operations result in new object or array references being created:
Put these operations in memoized selector functions to ensure that they only run if the input values have changed.
This will also ensure that if the input values haven't changed, mapStateToProps will still return the same result values as
before, and connect can skip re-rendering.
Transforming data can often be expensive (and usually results in new object references being created). In order for
your mapStateToProps function to be as fast as possible, you should only re-run these complex transformations when
the relevant data has changed.
Some transformations could be calculated in an action creator or reducer, and the transformed data could be
kept in the store
Immutable.js author Lee Byron on Twitter explicitly advises avoiding toJS when performance is a concern:
Perf tip for #immutablejs: avoid .toJS() .toObject() and .toArray() all slow full-copy operations which render
structural sharing useless.
There's several other performance concerns to take into consideration with Immutable.js - see the list of links at the
end of this page for more information.
The Redux combineReducers utility function tries to optimize for this. If none of the slice reducers returned a new
value, then combineReducers returns the old state object instead of a new one. This means that mutation in a reducer
can lead to the root state object not being updated, and thus the UI won't re-render.
With just (state), the function runs whenever the root store state object is different. With (state, ownProps), it runs
any time the store state is different and ALSO whenever the wrapper props have changed.
This means that you should not add the ownProps argument unless you actually need to use it, or your
mapStateToProps function will run more often than it needs to.
There are some edge cases around this behavior. The number of mandatory arguments determines whether
mapStateToProps will receive ownProps.
If the formal defnition of the function contains one mandatory parameter, mapStateToProps will not receive ownProps:
function mapStateToProps(state) {
console.log(state) // state
console.log(arguments[1]) // undefined
}
const mapStateToProps = (state, ownProps = {}) => {
console.log(state) // state
console.log(ownProps) // {}
}
It will receive ownProps when the formal defnition of the function contains zero or two mandatory parameters:
function mapStateToProps() {
console.log(arguments[0]) // state
console.log(arguments[1]) // ownProps
}
function mapStateToProps(...args) {
console.log(args[0]) // state
console.log(args[1]) // ownProps
}
Tutorials
Performance
Lee Byron's Tweet Suggesting to avoid toJS, toArray and toObject for Performance
Improving React and Redux performance with Reselect
Immutable data performance links
Q&A
As the second argument passed in to connect, mapDispatchToProps is used for dispatching actions to the store.
dispatch is a function of the Redux store. You call store.dispatch to dispatch an action.
With React Redux, your components never access the store directly - connect does it for you.
By default, a connected component receives props.dispatch and can dispatch actions itself.
connect can accept an argument called mapDispatchToProps, which lets you create functions that dispatch when
called, and pass those functions as props to your component.
The mapDispatchToProps functions are normally referred to as mapDispatch for short, but the actual variable name
used can be whatever you want.
If you don't specify the second argument to connect(), your component will receive dispatch by default. For example:
connect()(MyComponent)
// which is equivalent with
connect(null, null)(MyComponent)
// or
connect(mapStateToProps /** no second argument */)(MyComponent)
Once you have connected your component in this way, your component receives props.dispatch. You may use it to
dispatch actions to the store.
Providing a mapDispatchToProps allows you to specify which actions your component might need to dispatch. It lets
you provide action dispatching functions as props. Therefore, instead of calling props.dispatch(() => increment()),
you may call props.increment() directly. There are a few reasons why you might want to do that.
More Declarative
First, encapsulating the dispatch logic into function makes the implementation more declarative.
Dispatching an action
and letting the Redux store handle the data fow is how to implement the behavior, rather than what it does.
A good example would be dispatching an action when a button is clicked. Connecting the button directly probably
doesn't make sense conceptually, and neither does having the button reference dispatch.
Once you've wrapped all our action creators with functions that dispatch the actions, the component is free of the
Therefore, if you defne your own mapDispatchToProps, the connected component will no longer
need of dispatch.
receive dispatch.
In addition, you also gain the ability to pass down the action dispatching functions to child ( likely unconnected )
components.
This allows more components to dispatch actions, while keeping them "unaware" of Redux.
This is what React Redux’s connect does — it encapsulates the logic of talking to the Redux store and lets you not
worry about it. And this is what you should totally make full use of in your implementation.
The mapDispatchToProps parameter can be of two forms. While the function form allows more customization, the
object form is easy to use.
Function form: Allows more customization, gains access to dispatch and optionally ownProps
Object shorthand form: More declarative and easier to use
⭐ Note: We recommend using the object form of mapDispatchToProps unless you specifcally need to
customize dispatching behavior in some way.
Defning mapDispatchToProps as a function gives you the most fexibility in customizing the functions your component
receives, and how they dispatch actions.
Arguments
1. dispatch
2. ownProps (optional)
dispatch
The mapDispatchToProps function will be called with dispatch as the frst argument.
You will also likely want to forward arguments to your action creators:
const mapDispatchToProps = (dispatch) => {
return {
// explicitly forwarding arguments
onClick: (event) => dispatch(trackClick(event)),
ownProps ( optional )
If your mapDispatchToProps function is declared as taking two parameters, it will be called with dispatch as the frst
parameter and the props passed to the connected component as the second parameter, and will be re-invoked
whenever the connected component receives new props.
This means, instead of re-binding new props to action dispatchers upon component re-rendering, you may do so when
your component's props change.
render() {
return <button onClick={() => this.props.toggleTodo(this.props.todoId)} />
}
render() {
return <button onClick={() => this.props.toggleTodo()} />
}
Return
Your mapDispatchToProps function should return a plain object:
Each feld in the object will become a separate prop for your own component, and the value should normally be a
function that dispatches an action when called.
If you use action creators ( as oppose to plain object actions ) inside dispatch, it is a convention to simply name
the feld key the same name as the action creator:
The return of the mapDispatchToProps function will be merged to your connected component as props. You may call
them directly to dispatch its action.
Wrapping these functions by hand is tedious, so Redux provides a function to simplify that.
bindActionCreators turns an object whose values are action creators, into an object with the same keys, but
with every action creator wrapped into a dispatch call so they may be invoked directly. See Redux Docs on
bindActionCreators
The wrapper functions generated by bindActionCreators will automatically forward all of their arguments, so you
don't need to do that by hand.
function mapDispatchToProps(dispatch) {
return bindActionCreators({ increment, decrement, reset }, dispatch)
}
If the mapDispatchToProps argument is supplied, the component will no longer receive the default dispatch. You may
bring it back by adding it manually to the return of your mapDispatchToProps, although most of the time you shouldn’t
need to do this:
import { bindActionCreators } from 'redux'
// ...
function mapDispatchToProps(dispatch) {
return {
dispatch,
...bindActionCreators({ increment, decrement, reset }, dispatch),
}
}
You’ve seen that the setup for dispatching Redux actions in a React component follows a very similar process: defne
an action creator, wrap it in another function that looks like (…args) => dispatch(actionCreator(…args)), and pass
that wrapper function as a prop to your component.
Because this is so common, connect supports an “object shorthand” form for the mapDispatchToProps argument: if
you pass an object full of action creators instead of a function, connect will automatically call bindActionCreators for
you internally.
We recommend always using the “object shorthand” form of mapDispatchToProps, unless you have a specifc
reason to customize the dispatching behavior.
Note that:
const mapDispatchToProps = {
increment,
decrement,
reset,
}
Since the actual name of the variable is up to you, you might want to give it a name like actionCreators, or even defne
the object inline in the call to connect:
// or
export default connect(mapState, { increment, decrement, reset })(Counter)
Common Problems
Also known as
This is a common error that happens when you try to call this.props.dispatch , but dispatch is not injected to your
component.
The default mapDispatchToProps is simply dispatch => ({ dispatch }). If you do not provide mapDispatchToProps,
dispatch will be provided as mentioned above.
You may bring back dispatch by providing your customized mapDispatchToProps function:
function mapDispatchToProps(dispatch) {
return {
dispatch,
...bindActionCreators({ increment, decrement, reset }, dispatch),
}
}
There are discussions regarding whether to provide dispatch to your components when you specify
mapDispatchToProps ( Dan Abramov’s response to #255 ). You may read them for further understanding of the current
implementation intention.
Yes. You can skip the frst parameter by passing undefined or null. Your component will not subscribe to the store,
and will still receive the dispatch props defned by mapDispatchToProps.
connect(null, mapDispatchToProps)(MyComponent)
It's an anti-pattern to interact with the store directly in a React component, whether it's an explicit import of the store
or accessing it via context (see the Redux FAQ entry on store setup for more details). Let React Redux’s connect handle
the access to the store, and use the dispatch it passes to the props to dispatch actions.
Tutorials
Related Docs
Q&A
How to get simple dispatch from this.props using connect with Redux?
this.props.dispatch is undefined if using mapDispatchToProps
As part of that, React Redux abstracts away the details of which store you are using, and the exact details of how that
store interaction is handled. In typical usage, your own components should never need to care about those details, and
won't ever reference the store directly. React Redux also internally handles the details of how the store and state are
propagated to connected components, so that this works as expected by default.
However, there may be certain use cases where you may need to customize how the store and state are propagated to
connected components, or access the store directly. Here are some examples of how to do this.
React Redux's <Provider> component uses <ReactReduxContext.Provider> to put the Redux store and the current
store
state into context, and connect uses <ReactReduxContext.Consumer> to read those values and handle updates.
The useStore hook returns the current store instance from the default ReactReduxContext. If you truly need to access
the store, this is the recommended approach.
Instead of using the default context instance from React Redux, you may supply your own custom context instance.
If you supply a custom context, React Redux will use that context instance instead of the one it creates and exports by
default.
After you’ve supplied the custom context to <Provider />, you will need to supply this context instance to all of your
connected components that are expected to connect to the same store:
The following runtime error occurs when React Redux does not fnd a store in the context it is looking. For example:
You provided a custom context instance to <Provider />, but did not provide the same instance (or did not
provide any) to your connected components.
You provided a custom context to your connected component, but did not provide the same instance (or did not
provide any) to <Provider />.
Invariant Violation
Could not fnd "store" in the context of "Connect(MyComponent)". Either wrap the root component in a
<Provider>, or pass a custom React context provider to <Provider> and the corresponding React context
consumer to Connect(Todo) in connect options.
To access the custom context via the hooks API, you can create custom hooks via the hook creator functions.
Multiple Stores
// You may also pass the alternate context instance directly to the connected component instead
<ConnectedMyComponentA context={ContextA} />
In rare cases, you may need to access the Redux store directly in your own components. This can be done by rendering
the appropriate context consumer yourself, and accessing the store feld out of the context value.
CAUTION
This is not considered part of the React Redux public API, and may break without notice. We do recognize
that the
community has use cases where this is necessary, and will try to make it possible for users to build additional
functionality on top of React Redux, but our specifc use of context is considered an implementation detail.
If you have
additional use cases that are not sufciently covered by the current APIs, please fle an issue to discuss
possible API
improvements.
import { ReactReduxContext } from 'react-redux'
Further Resources
CodeSandbox example: A reading list app with theme using a separate store, implemented by providing
(multiple) custom context(s).
Related issues:
#1132: Update docs for using a different store key
#1126: <Provider> misses state changes that occur between when its constructor runs and when it mounts
Provider
Overview
The <Provider> component makes the Redux store available to any nested components that need to access the
Redux store.
Since any React component in a React Redux app can be connected to the store, most applications will render a
<Provider> at the top level, with the entire app’s component tree inside of it.
The Hooks and connect APIs can then access the provided store instance via React's Context mechanism.
Props
/**
* An optional server state snapshot. Will be used during initial hydration render
* if available, to ensure that the UI output is consistent with the HTML generated on the server.
* New in 8.0
*/
serverState?: S
/**
* Optional context to be used internally in react-redux. Use React.createContext()
* to create a context to be used.
* If this is used, you'll need to customize `connect` by supplying the same
* context provided to the Provider.
* Initial value doesn't matter, as it is overwritten with the internal state of Provider.
*/
context?: Context<ReactReduxContextValue<S, A>>
/** The top-level React elements in your component tree, such as `<App />` **/
children: ReactNode
}
You may provide a context instance. If you do so, you will need to provide the same context instance to all of your
connected components as well. Failure to provide the correct context results in this runtime error:
Invariant Violation
Could not fnd "store" in the context of "Connect(MyComponent)". Either wrap the root component in a
<Provider>, or pass a custom React context provider to <Provider> and the corresponding React context
consumer to Connect(Todo) in connect options.
As of React-Redux v8, <Provider> now accepts a serverState prop for use in SSR hydration scenarios. This is
necessary if you are calling hydrateRoot in order to avoid hydration mismatches.
You should pass the entire serialized state from the server as the serverState prop, and React will use this state for
the initial hydration render. After that, it will apply any updates from changes that occurred on the client during the
setup process.
Examples
Basic Usage
In the example below, the <App /> component is our root-level component. This means it’s at the very top of our
component hierarchy.
// As of React 18
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
<Provider store={store}>
<App />
</Provider>
)
window. The serialized state is used to both pre-fll the store's contents, and passed as the serverState prop to
<Provider>
src/index.ts
import { hydrateRoot } from 'react-dom/client'
import { configureStore } from '@reduxjs/toolkit'
import { Provider } from 'react-redux'
hydrateRoot(
document.getElementById('root'),
<Provider store={clientStore} serverState={preloadedState}>
<App />
</Provider>
)
Hooks
React's new "hooks" APIs give function components the ability to use local component state, execute side effects, and
more. React also lets us write custom hooks, which let us extract reusable hooks to add our own behavior on top of
React's built-in hooks.
React Redux includes its own custom hook APIs, which allow your React components to subscribe to the Redux store
and dispatch actions.
TIP
We recommend using the React-Redux hooks API as the default approach in your React components.
The existing connect API still works and will continue to be supported, but the hooks API is simpler and works better
with TypeScript.
As with connect(), you should start by wrapping your entire application in a <Provider> component to make the store
available throughout the component tree:
// As of React 18
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
<Provider store={store}>
<App />
</Provider>
)
From there, you may import any of the listed React Redux hooks APIs and use them within your function components.
useSelector()
Allows you to extract data from the Redux store state, using a selector function.
INFO
The selector function should be pure since it is potentially executed multiple times and at arbitrary points in time.
The selector is approximately equivalent to the mapStateToProps argument to connect conceptually. The selector will
be called with the entire Redux store state as its only argument. The selector will be run whenever the function
component renders (unless its reference hasn't changed since a previous render of the component so that a cached
result can be returned by the hook without re-running the selector). useSelector() will also subscribe to the Redux
store, and run your selector whenever an action is dispatched.
However, there are some differences between the selectors passed to useSelector() and a mapState function:
The selector may return any value as a result, not just an object. The return value of the selector will be used as
the return value of the useSelector() hook.
When an action is dispatched, useSelector() will do a reference comparison of the previous selector result value
and the current result value. If they are different, the component will be forced to re-render. If they are the
same, the component will not re-render.
The selector function does not receive an ownProps argument. However, props can be used through closure (see
the examples below) or by using a curried selector.
Extra care must be taken when using memoizing selectors (see examples below for more details).
useSelector() uses strict === reference equality checks by default, not shallow equality (see the following section
for more details).
INFO
There are potential edge cases with using props in selectors that may cause issues. See the Usage Warnings section of
this page for further details.
You may call useSelector() multiple times within a single function component. Each call to useSelector() creates an
individual subscription to the Redux store. Because of the React update batching behavior used in React Redux v7, a
dispatched action that causes multiple useSelector()s in the same component to return new values should only result
in a single re-render.
When the function component renders, the provided selector function will be called and its result will be returned
from
the useSelector() hook. (A cached result may be returned by the hook without re-running the selector if it's the same
function reference as on a previous render of the component.)
However, when an action is dispatched to the Redux store, useSelector() only forces a re-render if the selector result
appears to be different than the last result. The default comparison is a strict === reference
comparison. This is
different than connect(), which uses shallow equality checks on the results of mapState calls
to determine if re-
rendering is needed. This has several implications on how you should use useSelector().
With mapState, all individual felds were returned in a combined object. It didn't matter if the return object was
a new
reference or not - connect() just compared the individual felds. With useSelector(), returning a new object
every time
will always force a re-render by default. If you want to retrieve multiple values from the store, you can:
Call useSelector() multiple times, with each call returning a single feld value
Use Reselect or a similar library to create a memoized selector that returns multiple values in one object, but
only
returns a new object when one of the values has changed.
Use the shallowEqual function from React-Redux as the equalityFn argument to useSelector(), like:
// later
const selectedData = useSelector(selectorReturningObject, shallowEqual)
The optional comparison function also enables using something like Lodash's _.isEqual() or Immutable.js's
comparison capabilities.
useSelector Examples
Basic usage:
When using useSelector with an inline selector as shown above, a new instance of the selector is created whenever
the component is rendered. This works as long as the selector does not maintain any state. However, memoizing
selectors (e.g. created via createSelector from reselect) do have internal state, and therefore care must be taken
when using them. Below you can fnd typical usage scenarios for memoizing selectors.
When the selector does only depend on the state, simply ensure that it is declared outside of the component so that
the same selector instance is used for each render:
The same is true if the selector depends on the component's props, but will only ever be used in a single instance of a
single component:
return <div>{matchingCount}</div>
}
However, when the selector is used in multiple component instances and depends on the component's props, you
need to ensure that each component instance gets its own selector instance (see here for a more thorough
explanation of why this is necessary):
return <div>{matchingCount}</div>
}
useDispatch()
This hook returns a reference to the dispatch function from the Redux store. You may use it to dispatch actions as
needed.
Examples
return (
<div>
<span>{value}</span>
<button onClick={() => dispatch({ type: 'increment-counter' })}>
Increment counter
</button>
</div>
)
}
When passing a callback using dispatch to a child component, you may sometimes want to memoize it with
useCallback. If the child component is trying to optimize render behavior using React.memo() or similar, this avoids
unnecessary rendering of child components due to the changed callback reference.
return (
<div>
<span>{value}</span>
<MyIncrementButton onIncrement={incrementCounter} />
</div>
)
}
The dispatch function reference will be stable as long as the same store instance is being passed to the <Provider>.
Normally, that store instance never changes in an application.
However, the React hooks lint rules do not know that dispatch should be stable, and will warn that the dispatch
variable
should be added to dependency arrays for useEffect and useCallback. The simplest solution is to do just that:
useEffect(() => {
dispatch(fetchTodos())
// Safe to add dispatch to the dependencies array
}, [dispatch])
}
useStore()
This hook returns a reference to the same Redux store that was passed in to the <Provider> component.
This hook should probably not be used frequently. Prefer useSelector() as your primary choice. However, this may be
useful for less common scenarios that do require access to the store, such as replacing reducers.
Examples
Custom context
The <Provider> component allows you to specify an alternate context via the context prop. This is useful if you're
building a complex reusable component, and you don't want your store to collide with any Redux store your
consumers' applications might use.
To access an alternate context via the hooks API, use the hook creator functions:
// Export your custom hooks if you wish to use them in other files.
export const useStore = createStoreHook(MyContext)
export const useDispatch = createDispatchHook(MyContext)
export const useSelector = createSelectorHook(MyContext)
Usage Warnings
INFO
The React-Redux hooks API has been production-ready since we released it in v7.1.0, and we recommend using the
hooks API as the default approach in your components. However, there are a couple of edge cases that can occur,
and we're documenting those so that you can be aware of them.
In practice, these are a rare concern - we've received far more comments about these being in the docs than actual
reports of these being a real problem in an app.
One of the most difcult aspects of React Redux's implementation is ensuring that if your mapStateToProps function is
defned as (state, ownProps), it will be called with the "latest" props every time. Up through version 4, there were
recurring bugs reported involving edge case situations, such as errors thrown from a mapState function for a list item
whose data had just been deleted.
Starting with version 5, React Redux has attempted to guarantee that consistency with ownProps. In version 7, that is
implemented using a custom Subscription class internally in connect(), which forms a nested hierarchy. This ensures
that connected components lower in the tree will only receive store update notifcations once the nearest connected
ancestor has been updated. However, this relies on each connect() instance overriding part of the internal React
context, supplying its own unique Subscription instance to form that nesting, and rendering the
<ReactReduxContext.Provider> with that new context value.
With hooks, there is no way to render a context provider, which means there's also no nested hierarchy of
subscriptions. Because of this, the "stale props" and "zombie child" issues may potentially re-occur in an app that
Depending on what props were used and what the current store state is, this may result in incorrect data being
returned from the selector, or even an error being thrown.
Multiple nested connected components are mounted in a frst pass, causing a child component to subscribe to
the store before its parent
An action is dispatched that deletes data from the store, such as a todo item
The parent component would stop rendering that child as a result
However, because the child subscribed frst, its subscription runs before the parent stops rendering it. When it
reads a value from the store based on props, that data no longer exists, and if the extraction logic is not careful,
this may result in an error being thrown.
useSelector() tries to deal with this by catching all errors that are thrown when the selector is executed due to a
store update (but not when it is executed during rendering). When an error occurs, the component will be forced to
render, at which point the selector is executed again. This works as long as the selector is a pure function and you do
not depend on the selector throwing errors.
If you prefer to deal with this issue yourself, here are some possible options for avoiding these problems altogether
with useSelector():
just reach straight into state.todos[props.id].name - read state.todos[props.id] frst, and verify that it exists
before trying to read todo.name.
Because connect adds the necessary Subscription to the context provider and delays evaluating child
subscriptions until the connected component has re-rendered, putting a connected component in the
component tree just above the component using useSelector will prevent these issues as long as the connected
component gets re-rendered due to the same store update as the hooks component.
INFO
Performance
As mentioned earlier, by default useSelector() will do a reference equality comparison of the selected value when
running the selector function after an action is dispatched, and will only cause the component to re-render if the
selected value changed. However, unlike connect(), useSelector() does not prevent the component from re-
rendering due to its parent re-rendering, even if the component's props did not change.
If further performance optimizations are necessary, you may consider wrapping your function component in
React.memo():
Hooks Recipes
We've pared down our hooks API from the original alpha release, focusing on a more minimal set of API primitives.
However, you may still wish to use some of the approaches we tried in your own apps. These examples should be
ready
Recipe: useActions()
This hook was in our original alpha release, but removed in v7.1.0-alpha.4, based on Dan Abramov's suggestion.
That
suggestion was based on "binding action creators" not being as useful in a hooks-based use case, and causing too
much conceptual overhead and syntactic complexity.
You should probably prefer to call the useDispatch hook in your components to retrieve a reference to dispatch,
and
manually call dispatch(someActionCreator()) in callbacks and effects as needed. You may also use the Redux
bindActionCreators function in your own code to bind action creators,
However, if you'd like to still use this hook yourself, here's a copy-pastable version that supports passing in action
creators as a single function, an array, or an object.
Recipe: useShallowEqualSelector()
There are some architectural trade offs to take into consideration when deciding whether to use hooks or not. Mark
Erikson summarizes these nicely in his two blog posts Thoughts on React Hooks, Redux, and Separation of Concerns
and Hooks, HOCs, and Tradeoffs.
connect()
TIP
connect still works and is supported in React-Redux 8.x. However, we recommend using the hooks API as the
default.
Overview
It provides its connected component with the pieces of the data it needs from the store, and the functions it can use
to dispatch actions to the store.
It does not modify the component class passed to it; instead, it returns a new, connected component class that wraps
the component you passed in.
The mapStateToProps and mapDispatchToProps deals with your Redux store’s state and dispatch, respectively. state
and dispatch will be supplied to your mapStateToProps or mapDispatchToProps functions as the frst argument.
The returns of mapStateToProps and mapDispatchToProps are referred to internally as stateProps and dispatchProps,
respectively. They will be supplied to mergeProps, if defned, as the frst and the second argument, where the third
argument will be ownProps. The combined result, commonly referred to as mergedProps, will then be supplied to your
connected component.
connect() Parameters
connect accepts four different parameters, all optional. By convention, they are called:
1. mapStateToProps?: Function
3. mergeProps?: Function
4. options?: Object
Parameters
1. state: Object
2. ownProps?: Object
A mapStateToProps function takes a maximum of two parameters. The number of declared function parameters (a.k.a.
arity) affects when it will be called. This also determines whether the function will receive ownProps. See notes here.
state
If your mapStateToProps function is declared as taking one parameter, it will be called whenever the store state
changes, and given the store state as the only parameter.
ownProps
If your mapStateToProps function is declared as taking two parameters, it will be called whenever the store state
changes or when the wrapper component receives new props (based on shallow equality comparisons). It will be
given the store state as the frst parameter, and the wrapper component's props as the second parameter.
Returns
Your mapStateToProps functions are expected to return an object. This object, normally referred to as stateProps, will
be merged as props to your connected component. If you defne mergeProps, it will be supplied as the frst parameter
to mergeProps.
The return of the mapStateToProps determine whether the connected component will re-render (details here).
For more details on recommended usage of mapStateToProps, please refer to our guide on using mapStateToProps.
You may defne mapStateToProps and mapDispatchToProps as a factory function, i.e., you return a function
instead of an object. In this case your returned function will be treated as the real mapStateToProps or
mapDispatchToProps, and be called in subsequent calls. You may see notes on Factory Functions or our
guide on performance optimizations.
Conventionally called mapDispatchToProps, this second parameter to connect() may either be an object, a function, or
not supplied.
Your component will receive dispatch by default, i.e., when you do not supply a second parameter to connect():
If you defne a mapDispatchToProps as a function, it will be called with a maximum of two parameters.
Parameters
1. dispatch: Function
2. ownProps?: Object
dispatch
If your mapDispatchToProps is declared as a function taking one parameter, it will be given the dispatch of your store.
ownProps
If your mapDispatchToProps function is declared as taking two parameters, it will be called with dispatch as the frst
parameter and the props passed to the wrapper component as the second parameter, and will be re-invoked
whenever the connected component receives new props.
The second parameter is normally referred to as ownProps by convention.
The number of declared function parameters of mapDispatchToProps determines whether they receive ownProps. See
notes here.
Returns
Your mapDispatchToProps functions are expected to return an object. Each felds of the object should be a function,
calling which is expected to dispatch an action to the store.
The return of your mapDispatchToProps functions are regarded as dispatchProps. It will be merged as props to your
connected component. If you defne mergeProps, it will be supplied as the second parameter to mergeProps.
For more details on recommended usage, please refer to our guide on using mapDispatchToProps.
You may defne mapStateToProps and mapDispatchToProps as a factory function, i.e., you return a function
instead of an object. In this case your returned function will be treated as the real mapStateToProps or
mapDispatchToProps, and be called in subsequent calls. You may see notes on Factory Functions or our
guide on performance optimizations.
const mapDispatchToProps = {
addTodo,
deleteTodo,
toggleTodo,
}
In this case, React-Redux binds the dispatch of your store to each of the action creators using bindActionCreators.
The result will be regarded as dispatchProps, which will be either directly merged to your connected components, or
supplied to mergeProps as the second argument.
We also have a section in our mapDispatchToProps guide on the usage of object shorthand form here.
If specifed, defnes how the fnal props for your own wrapped component are determined. If you do not provide
Parameters
mergeProps should be specifed with maximum of three parameters. They are the result of mapStateToProps(),
1. stateProps
2. dispatchProps
3. ownProps
The felds in the plain object you return from it will be used as the props for the wrapped component. You may specify
this function to select a slice of the state based on props, or to bind action creators to a particular variable from props.
Returns
The return value of mergeProps is referred to as mergedProps and the felds will be used as the props for the wrapped
component.
Note: Creating new values in mergeProps will cause re-renders. It is recommended that you memoize felds
in order to avoid unnecessary re-renders.
options?: Object
{
context?: Object,
areStatesEqual?: Function,
areOwnPropsEqual?: Function,
areStatePropsEqual?: Function,
areMergedPropsEqual?: Function,
forwardRef?: boolean,
}
context: Object
instance of your context to both <Provider /> and your connected component.
You may wish to override areStatesEqual if your mapStateToProps function is computationally expensive and is also
only concerned with a small slice of your state. The example above will effectively ignore state changes for everything
but that slice of state.
This would likely impact the other equality checks as well, depending on your mapStateToProps function.
areOwnPropsEqual: (next: Object, prev: Object) => boolean
You may wish to override areOwnPropsEqual as a way to whitelist incoming props. You'd also have to implement
mapStateToProps, mapDispatchToProps and mergeProps to also whitelist props. (It may be simpler to achieve this other
type: function
default value: shallowEqual
You may wish to override areStatePropsEqual to use strictEqual if your mapStateToProps uses a memoized selector
that will only return a new object if a relevant prop has changed. This would be a very slight performance
improvement, since would avoid extra equality checks on individual props each time mapStateToProps is called.
You may wish to override areMergedPropsEqual to implement a deepEqual if your selectors produce complex props.
ex: nested objects, new arrays, etc. (The deep equal check may be faster than just re-rendering.)
forwardRef: boolean
If {forwardRef : true} has been passed to connect, adding a ref to the connected wrapper component will actually
return the instance of the wrapped component.
connect() Returns
The return of connect() is a wrapper function that takes your component and returns a wrapper component with the
additional props it injects.
// first call: returns a hoc that you can use to wrap any component
const connectUser = connect(mapState, mapDispatch)
In most cases, the wrapper function will be called right away, without being saved in a temporary variable:
Example Usage
Because connect is so fexible, it may help to see some additional examples of how it can be called:
Inject all action creators (addTodo, completeTodo, ...) without subscribing to the store
Don’t do this! It kills any performance optimizations because TodoApp will rerender after every state change.
It’s better to have more granular connect() on several components in your view hierarchy that each only
listen to a relevant slice of the state.
// don't do this!
export default connect((state) => state)(TodoApp)
function mapStateToProps(state) {
return { todos: state.todos }
}
function mapStateToProps(state) {
return { todos: state.todos }
}
Inject todos and all action creators (addTodo, completeTodo, ...) as actions
function mapStateToProps(state) {
return { todos: state.todos }
}
function mapDispatchToProps(dispatch) {
return { actions: bindActionCreators(actionCreators, dispatch) }
}
function mapStateToProps(state) {
return { todos: state.todos }
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({ addTodo }, dispatch)
}
export default connect(mapStateToProps, mapDispatchToProps)(TodoApp)
Inject todos and specifc action creators (addTodo and deleteTodo) with shorthand syntax
function mapStateToProps(state) {
return { todos: state.todos }
}
const mapDispatchToProps = {
addTodo,
deleteTodo,
}
function mapStateToProps(state) {
return { todos: state.todos }
}
function mapDispatchToProps(dispatch) {
return {
todoActions: bindActionCreators(todoActionCreators, dispatch),
counterActions: bindActionCreators(counterActionCreators, dispatch),
}
}
function mapStateToProps(state) {
return { todos: state.todos }
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(
{ ...todoActionCreators, ...counterActionCreators },
dispatch
),
}
}
function mapStateToProps(state) {
return { todos: state.todos }
}
function mapDispatchToProps(dispatch) {
return bindActionCreators(
{ ...todoActionCreators, ...counterActionCreators },
dispatch
)
}
Inject todos of a specifc user depending on props, and inject props.userId into the action
function mapStateToProps(state) {
return { todos: state.todos }
}
Notes
The number of declared function parameters of mapStateToProps and mapDispatchToProps determines whether they
receive ownProps
Note: ownProps is not passed to mapStateToProps and mapDispatchToProps if the formal defnition of the
function contains one mandatory parameter (function has length 1). For example, functions defned like
below won't receive ownProps as the second argument. If the incoming value of ownProps is undefined, the
default argument value will be used.
function mapStateToProps(state) {
console.log(state) // state
console.log(arguments[1]) // undefined
}
function mapStateToProps() {
console.log(arguments[0]) // state
console.log(arguments[1]) // ownProps
}
If your mapStateToProps or mapDispatchToProps functions return a function, they will be called once when the
component instantiates, and their returns will be used as the actual mapStateToProps, mapDispatchToProps, functions
respectively, in their subsequent calls.
The factory functions are commonly used with memoized selectors. This gives you the ability to create component-
instance-specifc selectors inside the closure:
While the connect API has stayed almost entirely API-compatible between all of our major versions, there have been
some small changes in options and behavior from version to version.
For details on the legacy 5.x and 6.x versions, please see these archived fles in the React Redux repo:
added in v7.0.0
INFO
If you're using React 18, you do not need to use the batch API. React 18 automatically batches all state updates, no
matter where they're queued.
React's unstable_batchedUpdates() API allows any React updates in an event loop tick to be batched together into a
single render pass. React already uses this internally for its own event handler callbacks. This API is actually part of the
renderer packages like ReactDOM and React Native, not the React core itself.
Since React-Redux needs to work in both ReactDOM and React Native environments, we've taken care of importing
this API from the correct renderer at build time for our own use. We also now re-export this function publicly
ourselves, renamed to batch(). You can use it to ensure that multiple actions dispatched outside of React only result
in a single render update, like this:
function myThunk() {
return (dispatch, getState) => {
// should only result in one combined re-render, not two
batch(() => {
dispatch(increment())
dispatch(increment())
})
}
}
References
The #redux channel of the Reactifux Discord community is our ofcial resource for all questions related to
learning and using Redux. Reactifux is a great place to hang out, ask questions, and learn - come join us!
You can also ask questions on Stack Overfow using the #redux tag.
In short,
Reducers should never mutate state, they must return new objects, or React Redux won’t see the updates.
Make sure you are actually dispatching actions. For example, if you have an action creator like addTodo, just
calling the imported addTodo() function by itself won't do anything because it just returns an action, but does not
dispatch it. You either need to call dispatch(addTodo()) (if using the hooks API) or props.addTodo() (if using
connect + mapDispatch).
1. Make sure you don’t have a duplicate instance of React on the page.
2. Make sure you don't have multiple instances/copies of React Redux in your project.
3. Make sure you didn’t forget to wrap your root or some other ancestor component in <Provider>.
4. Make sure you’re running the latest versions of React and React Redux.
Invariant Violation: addComponentAsRefTo(...): Only a ReactOwner can have refs. This usually
means that you’re trying to add a ref to a component that doesn’t have an owner
If you’re using React for web, this usually means you have a duplicate React. Follow the linked instructions to fx this.
ReactDOM emits this warning if useLayoutEffect is used "on the server". React Redux tries to get around the issue by
detecting whether it is running within a browser context. Jest, by default, defnes enough of the browser environment
that React Redux thinks it's running in a browser, causing these warnings.
You can prevent the warning by setting the @jest-environment for a single test fle:
// my.test.jsx
/**
* @jest-environment node
*/
Or by setting it globally:
// package.json
{
"name": "my-project",
"jest": {
"testEnvironment": "node"
}
}
See https://github.com/facebook/react/issues/14927#issuecomment-490426131