redux Documentation

A JS library for predictable global state management

61,509 stars TypeScript TypeScript 1 file ยท ~10,559 tokens #redux
RAW Doc

File: README.md

[Redux](https://redux.js.org)

Redux is a JS library for predictable and maintainable global state management.

It helps you write applications that behave consistently, run in different environments (client, server, and native), and are easy to test. On top of that, it provides a great developer experience, such as live code editing combined with a time traveling debugger.

You can use Redux together with React, or with any other view library. The Redux core is tiny (2kB, including dependencies), and has a rich ecosystem of addons.

Redux Toolkit is our official recommended approach for writing Redux logic. It wraps around the Redux core, and contains packages and functions that we think are essential for building a Redux app. Redux Toolkit builds in our suggested best practices, simplifies most Redux tasks, prevents common mistakes, and makes it easier to write Redux applications.



Installation

Create a React Redux App

The recommended way to start new apps with React and Redux Toolkit is by using our official Redux Toolkit + TS template for Vite, or by creating a new Next.js project using Next's with-redux template.

Both of these already have Redux Toolkit and React-Redux configured appropriately for that build tool, and come with a small example app that demonstrates how to use several of Redux Toolkit's features.

bash
# Vite with our Redux+TS template
# (using the `degit` tool to clone and extract the template)
npx degit reduxjs/redux-templates/packages/vite-template-redux my-app

# Next.js using the `with-redux` template
npx create-next-app --example with-redux my-app

We do not currently have official React Native templates, but recommend these templates for standard React Native and for Expo:

text
npm install @reduxjs/toolkit react-redux

For the Redux core library by itself:

text
npm install redux

For more details, see the Installation docs page.

Documentation

The Redux core docs are located at https://redux.js.org, and include the full Redux tutorials, as well usage guides on general Redux patterns:

The Redux Toolkit docs are available at https://redux-toolkit.js.org, including API references and usage guides for all of the APIs included in Redux Toolkit.

Learn Redux

Redux Essentials Tutorial

The Redux Essentials tutorial is a "top-down" tutorial that teaches "how to use Redux the right way", using our latest recommended APIs and best practices. We recommend starting there.

Redux Fundamentals Tutorial

The Redux Fundamentals tutorial is a "bottom-up" tutorial that teaches "how Redux works" from first principles and without any abstractions, and why standard Redux usage patterns exist.

Help and Discussion

The #redux channel of the Reactiflux Discord community is our official resource for all questions related to learning and using Redux. Reactiflux is a great place to hang out, ask questions, and learn - please come and join us there!

Before Proceeding Further

Redux is a valuable tool for organizing your state, but you should also consider whether it's appropriate for your situation. Please don't use Redux just because someone said you should - instead, please take some time to understand the potential benefits and tradeoffs of using it.

Here are some suggestions on when it makes sense to use Redux:

  • You have reasonable amounts of data changing over time
  • You need a single source of truth for your state
  • You find that keeping all your state in a top-level component is no longer sufficient

Yes, these guidelines are subjective and vague, but this is for a good reason. The point at which you should integrate Redux into your application is different for every user and different for every application.

For more thoughts on how Redux is meant to be used, please see:

Basic Example

The whole global state of your app is stored in an object tree inside a single store.
The only way to change the state tree is to create an action, an object describing what happened, and dispatch it to the store.
To specify how state gets updated in response to an action, you write pure reducer functions that calculate a new state based on the old state and the action.

Redux Toolkit simplifies the process of writing Redux logic and setting up the store. With Redux Toolkit, the basic app logic looks like:

js
import { createSlice, configureStore } from '@reduxjs/toolkit'

const counterSlice = createSlice({
  name: 'counter',
  initialState: {
    value: 0
  },
  reducers: {
    incremented: state => {
      // Redux Toolkit allows us to write "mutating" logic in reducers. It
      // doesn't actually mutate the state because it uses the Immer library,
      // which detects changes to a "draft state" and produces a brand new
      // immutable state based off those changes
      state.value += 1
    },
    decremented: state => {
      state.value -= 1
    }
  }
})

export const { incremented, decremented } = counterSlice.actions

const store = configureStore({
  reducer: counterSlice.reducer
})

// Can still subscribe to the store
store.subscribe(() => console.log(store.getState()))

// Still pass action objects to `dispatch`, but they're created for us
store.dispatch(incremented())
// {value: 1}
store.dispatch(incremented())
// {value: 2}
store.dispatch(decremented())
// {value: 1}

Redux Toolkit allows us to write shorter logic that's easier to read, while still following the original core Redux behavior and data flow.

You can find the official logo on GitHub.

Change Log

This project adheres to Semantic Versioning.
Every release, along with the migration instructions, is documented on the GitHub Releases page.

License

MIT


File: docs/components/_FundamentalsWarning.mdx

:::caution

Note that this tutorial intentionally shows older-style Redux logic patterns that require more code than the "modern Redux" patterns with Redux Toolkit we teach as the right approach for building apps with Redux today, in order to explain the principles and concepts behind Redux. It's not meant to be a production-ready project.

See these pages to learn how to use "modern Redux" with Redux Toolkit:

:::


File: docs/api/api-reference.md


id: api-reference title: API Reference

API Reference

This section documents the original Redux core API. The Redux core is small - it defines a set of contracts for you to implement (such as reducers) and provides a few helper functions to tie these contracts together.

In practice, you won't use the Redux core directly. Redux Toolkit is our official recommended approach for writing Redux logic. It wraps around the Redux core, and contains packages and functions that we think are essential for building a Redux app. Redux Toolkit builds in our suggested best practices, simplifies most Redux tasks, prevents common mistakes, and makes it easier to write Redux applications. Additionally, React-Redux lets your React components talk to the Redux store.

See their API docs here:

:::danger

The original Redux core createStore method is deprecated!

createStore will continue to work indefinitely, but we discourage direct use of createStore or the original redux package.

Instead, you should use the configureStore method from our official Redux Toolkit package, which wraps createStore to provide a better default setup and configuration approach. You should also use Redux Toolkit's createSlice method for writing reducer logic.

Redux Toolkit also re-exports all of the other APIs included in the redux package as well.

See the Migrating to Modern Redux page for details on how to update your existing legacy Redux codebase to use Redux Toolkit.

:::

Top-Level Exports

Store API


File: docs/api/applyMiddleware.md


id: applymiddleware title: applyMiddleware hide_title: true

 

`applyMiddleware(...middleware)`

Overview

Middleware is the suggested way to extend Redux with custom functionality. Middleware lets you wrap the store's dispatch method for fun and profit. The key feature of middleware is that it is composable. Multiple middleware can be combined together, where each middleware requires no knowledge of what comes before or after it in the chain.

:::warning Warning

You shouldn't have to call applyMiddleware directly. Redux Toolkit's configureStore method automatically adds a default set of middleware to the store, or can accept a list of middleware to add.

:::

The most common use case for middleware is to support asynchronous actions without much boilerplate code or a dependency on a library like Rx. It does so by letting you dispatch async actions in addition to normal actions.

For example, redux-thunk lets the action creators invert control by dispatching functions. They would receive dispatch as an argument and may call it asynchronously. Such functions are called thunks. Another example of middleware is redux-promise. It lets you dispatch a Promise async action, and dispatches a normal action when the Promise resolves.

The original Redux createStore method does not understand what middleware are out of the box - it has to be configured with applyMiddleware to add that behavior. However, Redux Toolkit's configureStore method automatically adds middleware support by default.

Arguments

  • ...middleware (arguments): Functions that conform to the Redux middleware API. Each middleware receives Store's dispatch and getState functions as named arguments, and returns a function. That function will be given the next middleware's dispatch method, and is expected to return a function of action calling next(action) with a potentially different argument, or at a different time, or maybe not calling it at all. The last middleware in the chain will receive the real store's dispatch method as the next parameter, thus ending the chain. So, the middleware signature is ({ getState, dispatch }) => next => action.

Returns

(Function) A store enhancer that applies the given middleware. The store enhancer signature is createStore => createStore but the easiest way to apply it is to pass it to createStore() as the last enhancer argument.

Examples

Example: Custom Logger Middleware

js
import { createStore, applyMiddleware } from 'redux'
import todos from './reducers'

function logger({ getState }) {
  return next => action => {
    console.log('will dispatch', action)

    // Call the next dispatch method in the middleware chain.
    const returnValue = next(action)

    console.log('state after dispatch', getState())

    // This will likely be the action itself, unless
    // a middleware further in chain changed it.
    return returnValue
  }
}

const store = createStore(todos, ['Use Redux'], applyMiddleware(logger))

store.dispatch({
  type: 'ADD_TODO',
  text: 'Understand the middleware'
})
// (These lines will be logged by the middleware:)
// will dispatch: { type: 'ADD_TODO', text: 'Understand the middleware' }
// state after dispatch: [ 'Use Redux', 'Understand the middleware' ]

Example: Using Thunk Middleware for Async Actions

text
/* Detailed source-code truncated for AI context efficiency. */

Tips

  • Middleware only wraps the store's dispatch function. Technically, anything a middleware can do, you can do manually by wrapping every dispatch call, but it's easier to manage this in a single place and define action transformations on the scale of the whole project.

  • If you use other store enhancers in addition to applyMiddleware, make sure to put applyMiddleware before them in the composition chain because the middleware is potentially asynchronous. For example, it should go before redux-devtools because otherwise the DevTools won't see the raw actions emitted by the Promise middleware and such.

  • If you want to conditionally apply a middleware, make sure to only import it when it's needed:

    js
    let middleware = [a, b]
    if (process.env.NODE_ENV !== 'production') {
      const c = require('some-debug-middleware')
      const d = require('another-debug-middleware')
      middleware = [...middleware, c, d]
    }
    
    const store = createStore(
      reducer,
      preloadedState,
      applyMiddleware(...middleware)
    )

    This makes it easier for bundling tools to cut out unneeded modules and reduces the size of your builds.

  • Ever wondered what applyMiddleware itself is? It ought to be an extension mechanism more powerful than the middleware itself. Indeed, applyMiddleware is an example of the most powerful Redux extension mechanism called store enhancers. It is highly unlikely you'll ever want to write a store enhancer yourself. Another example of a store enhancer is redux-devtools. Middleware is less powerful than a store enhancer, but it is easier to write.

  • Middleware sounds much more complicated than it really is. The only way to really understand middleware is to see how the existing middleware works, and try to write your own. The function nesting can be intimidating, but most of the middleware you'll find are, in fact, 10-liners, and the nesting and composability is what makes the middleware system powerful.

  • To apply multiple store enhancers, you may use compose().


File: docs/api/bindActionCreators.md


id: bindactioncreators title: bindActionCreators hide_title: true

 

`bindActionCreators(actionCreators, dispatch)`

Overview

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.

Normally you should just call dispatch directly on your Store instance. If you use Redux with React, react-redux will provide you with the dispatch function so you can call it directly, too.

The only use case for bindActionCreators is when you want to pass some action creators down to a component that isn't aware of Redux, and you don't want to pass dispatch or the Redux store to it.

For convenience, you can also pass an action creator as the first argument, and get a dispatch wrapped function in return.

:::warning Warning

This was originally intended for use with the legacy React-Redux connect method. It still works, but is rarely needed.

:::

Parameters

  1. actionCreators (Function or Object): An action creator, or an object whose values are action creators.

  2. dispatch (Function): A dispatch function available on the Store instance.

Returns

(Function or Object): An object mimicking the original object, but with each function immediately dispatching the action returned by the corresponding action creator. If you passed a function as actionCreators, the return value will also be a single function.

Example

`TodoActionCreators.js`

js
export function addTodo(text) {
  return {
    type: 'ADD_TODO',
    text
  }
}

export function removeTodo(id) {
  return {
    type: 'REMOVE_TODO',
    id
  }
}

`SomeComponent.js`

js
import React from 'react'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'

import * as TodoActionCreators from './TodoActionCreators'
console.log(TodoActionCreators)
// {
//   addTodo: Function,
//   removeTodo: Function
// }

function TodoListContainer(props) {
  // Injected by react-redux:
  const { dispatch, todos } = props

  // Here's a good use case for bindActionCreators:
  // You want a child component to be completely unaware of Redux.
  // We create bound versions of these functions now so we can
  // pass them down to our child later.

  const boundActionCreators = useMemo(
    () => bindActionCreators(TodoActionCreators, dispatch),
    [dispatch]
  )
  console.log(boundActionCreators)
  // {
  //   addTodo: Function,
  //   removeTodo: Function
  // }

  useEffect(() => {
    // Note: this won't work:
    // TodoActionCreators.addTodo('Use Redux')

    // You're just calling a function that creates an action.
    // You must dispatch the action, too!

    // This will work:
    let action = TodoActionCreators.addTodo('Use Redux')
    dispatch(action)
  }, [])

  return <TodoList todos={todos} {...this.boundActionCreators} />

  // An alternative to bindActionCreators is to pass
  // just the dispatch function down, but then your child component
  // needs to import action creators and know about them.

  // return <TodoList todos={todos} dispatch={dispatch} />
}

export default connect(state => ({ todos: state.todos }))(TodoListContainer)

File: docs/api/combineReducers.md


id: combinereducers title: combineReducers hide_title: true

 

`combineReducers(reducers)`

Overview

The combineReducers helper function turns an object whose values are different "slice reducer" functions into a single combined reducer function you can pass to Redux Toolkit's configureStore (or the legacy createStore method)

The resulting combined reducer calls every slice reducer any time an action is dispatched, and gathers their results into a single state object. This enables splitting up reducer logic into separate functions, each managing their own slice of the state independently.

:::tip

This should be rarely needed - Redux Toolkit's configureStore method will automatically call combineReducers for you if you pass in an object of slice reducers:

ts
const store = configureStore({
  reducer: {
    posts: postsReducer,
    comments: commentsReducer
  }
})

You can still call combineReducers() yourself if you need to construct the root reducer manually first.

:::

State Slices

The state produced by combineReducers() namespaces the states of each reducer under their keys as passed to combineReducers()

Example:

js
rootReducer = combineReducers({potato: potatoReducer, tomato: tomatoReducer})
// This would produce the following state object
{
  potato: {
    // ... potatoes, and other state managed by the potatoReducer ...
  },
  tomato: {
    // ... tomatoes, and other state managed by the tomatoReducer, maybe some nice sauce? ...
  }
}

You can control state key names by using different keys for the reducers in the passed object. For example, you may call combineReducers({ todos: myTodosReducer, counter: myCounterReducer }) for the state shape to be { todos, counter }.

Arguments

  1. reducers (Object): An object whose values correspond to different reducer functions that need to be combined into one.
ts
combineReducers({
  posts: postsReducer,
  comments: commentsReducer
})

See the notes below for some rules every passed reducer must follow.

Returns

(Function): A reducer that invokes every reducer inside the reducers object, and constructs a state object with the same shape.

Notes

This function is mildly opinionated and is skewed towards helping beginners avoid common pitfalls. This is why it attempts to enforce some rules that you don't have to follow if you write the root reducer manually.

Any reducer passed to combineReducers must satisfy these rules:

  • For any action that is not recognized, it must return the state given to it as the first argument.

  • It must never return undefined. It is too easy to do this by mistake via an early return statement, so combineReducers throws if you do that instead of letting the error manifest itself somewhere else.

  • If the state given to it is undefined, it must return the initial state for this specific reducer. According to the previous rule, the initial state must not be undefined either. It is handy to specify it with optional arguments syntax, but you can also explicitly check the first argument for being undefined.

While combineReducers attempts to check that your reducers conform to some of these rules, you should remember them, and do your best to follow them. combineReducers will check your reducers by passing undefined to them; this is done even if you specify initial state to Redux.createStore(combineReducers(...), initialState). Therefore, you must ensure your reducers work properly when receiving undefined as state, even if you never intend for them to actually receive undefined in your own code.

Example

`reducers/todos.js`

js
export default function todos(state = [], action) {
  switch (action.type) {
    case 'ADD_TODO':
      return state.concat([action.text])
    default:
      return state
  }
}

`reducers/counter.js`

js
export default function counter(state = 0, action) {
  switch (action.type) {
    case 'INCREMENT':
      return state + 1
    case 'DECREMENT':
      return state - 1
    default:
      return state
  }
}

`reducers/index.js`

js
import { combineReducers } from '@reduxjs/toolkit'
import todos from './todos'
import counter from './counter'

export default combineReducers({
  todos,
  counter
})

`App.js`

js
import { configureStore } from '@reduxjs/toolkit'
import reducer from './reducers/index'

const store = configureStore({
  reducer
})
console.log(store.getState())
// {
//   counter: 0,
//   todos: []
// }

store.dispatch({
  type: 'ADD_TODO',
  text: 'Use Redux'
})
console.log(store.getState())
// {
//   counter: 0,
//   todos: [ 'Use Redux' ]
// }

Tips

  • This helper is just a convenience! You can write your own combineReducers that works differently, or even assemble the state object from the child reducers manually and write a root reducer function explicitly, like you would write any other function.

  • You may call combineReducers at any level of the reducer hierarchy. It doesn't have to happen at the top. In fact you may use it again to split the child reducers that get too complicated into independent grandchildren, and so on.


File: docs/api/compose.md


id: compose title: compose hide_title: true

 

`compose(...functions)`

Overview

Composes functions from right to left.

This is a functional programming utility, and is included in Redux as a convenience.
You might want to use it to apply several store enhancers in a row. compose is also usable as a general-purpose standalone method.

:::warning Warning

You shouldn't have to call compose directly. Redux Toolkit's configureStore method automatically configures a Redux store with the standard applyMiddleware and Redux DevTools store enhancers, and offers an enhancers argument to pass in additional enhancers.

:::

Arguments

  1. (arguments): The functions to compose. Each function is expected to accept a single parameter. Its return value will be provided as an argument to the function standing to the left, and so on. The exception is the right-most argument which can accept multiple parameters, as it will provide the signature for the resulting composed function.

Returns

(Function): The final function obtained by composing the given functions from right to left.

Example

This example demonstrates how to use compose to enhance a store with applyMiddleware and a few developer tools from the redux-devtools package.

js
import { createStore, applyMiddleware, compose } from 'redux'
import { thunk } from 'redux-thunk'
import DevTools from './containers/DevTools'
import reducer from '../reducers'

const store = createStore(
  reducer,
  compose(applyMiddleware(thunk), DevTools.instrument())
)

Tips

  • All compose does is let you write deeply nested function transformations without the rightward drift of the code. Don't give it too much credit!

File: docs/api/createStore.md


id: createstore title: createStore hide_title: true

 

`createStore(reducer, preloadedState?, enhancer?)`

Creates a Redux store that holds the complete state tree of your app.
There should only be a single store in your app.

:::danger

The original Redux core createStore method is deprecated!

createStore will continue to work indefinitely, but we discourage direct use of createStore or the original redux package.

Instead, you should use the configureStore method from our official Redux Toolkit package, which wraps createStore to provide a better default setup and configuration approach. You should also use Redux Toolkit's createSlice method for writing reducer logic.

Redux Toolkit also re-exports all of the other APIs included in the redux package as well.

See the Migrating to Modern Redux page for details on how to update your existing legacy Redux codebase to use Redux Toolkit.

:::

Arguments

  1. reducer (Function): A root reducer function that returns the next state tree, given the current state tree and an action to handle.

  2. [preloadedState] (any): The initial state. You may optionally specify it to hydrate the state from the server in universal apps, or to restore a previously serialized user session. If you produced reducer with combineReducers, this must be a plain object with the same shape as the keys passed to it. Otherwise, you are free to pass anything that your reducer can understand.

  3. [enhancer] (Function): The store enhancer. You may optionally specify it to enhance the store with third-party capabilities such as middleware, time travel, persistence, etc. The only store enhancer that ships with Redux is applyMiddleware().

Returns

(Store): An object that holds the complete state of your app. The only way to change its state is by dispatching actions. You may also subscribe to the changes to its state to update the UI.

Example

js
import { createStore } from 'redux'

function todos(state = [], action) {
  switch (action.type) {
    case 'ADD_TODO':
      return state.concat([action.text])
    default:
      return state
  }
}

const store = createStore(todos, ['Use Redux'])

store.dispatch({
  type: 'ADD_TODO',
  text: 'Read the docs'
})

console.log(store.getState())
// [ 'Use Redux', 'Read the docs' ]

Deprecation and Alternate `legacy_createStore` Export

In Redux 4.2.0, we marked the original createStore method as @deprecated. Strictly speaking, this is not a breaking change, nor is it new in 5.0, but we're documenting it here for completeness.

This deprecation is solely a visual indicator that is meant to encourage users to migrate their apps from legacy Redux patterns to use the modern Redux Toolkit APIs. The deprecation results in a visual strikethrough when imported and used, like createStore, but with no runtime errors or warnings.

createStore will continue to work indefinitely, and will not ever be removed. But, today we want all Redux users to be using Redux Toolkit for all of their Redux logic.

To fix this, there are three options:

  • Follow our strong suggestion to switch over to Redux Toolkit and configureStore
  • Do nothing. It's just a visual strikethrough, and it doesn't affect how your code behaves. Ignore it.
  • Switch to using the legacy_createStore API that is now exported, which is the exact same function but with no @deprecated tag. The simplest option is to do an aliased import rename, like import { legacy_createStore as createStore } from 'redux'

Tips

  • Don't create more than one store in an application! Instead, use combineReducers to create a single root reducer out of many.

  • Redux state is normally plain JS objects and arrays.

  • If your state is a plain object, make sure you never mutate it! Immutable updates require making copies of each level of data, typically using the object spread operator ( return { ...state, ...newData } ).

  • For universal apps that run on the server, create a store instance with every request so that they are isolated. Dispatch a few data fetching actions to a store instance and wait for them to complete before rendering the app on the server.

  • When a store is created, Redux dispatches a dummy action to your reducer to populate the store with the initial state. You are not meant to handle the dummy action directly. Just remember that your reducer should return some kind of initial state if the state given to it as the first argument is undefined, and you're all set.

  • To apply multiple store enhancers, you may use compose().


File: docs/api/Store.md


id: store title: Store

Store

A store holds the whole state tree of your application.
The only way to change the state inside it is to dispatch an action on it, which triggers the root reducer function to calculate the new state.

A store is not a class. It's just an object with a few methods on it.

To create a store, pass your root reducer function to Redux Toolkit's configureStore method, which will set up a Redux store with a good default configuration. (Alternately, if you're not yet using Redux Toolkit, you can use the original createStore method, but we encourage you to migrate your code to use Redux Toolkit as soon as possible)

Store Methods

getState()

Returns the current state tree of your application.
It is equal to the last value returned by the store's reducer.

Returns

(any): The current state tree of your application.


 

dispatch(action)

Dispatches an action. This is the only way to trigger a state change.

The store's reducer function will be called with the current getState() result and the given action synchronously. Its return value will be considered the next state. It will be returned from getState() from now on, and the change listeners will immediately be notified.

:::caution

If you attempt to call dispatch from inside the reducer, it will throw with an error saying "Reducers may not dispatch actions." Reducers are pure functions - they can only return a new state value and must not have side effects (and dispatching is a side effect).

In Redux, subscriptions are called after the root reducer has returned the new state, so you may dispatch in the subscription listeners. You are only disallowed to dispatch inside the reducers because they must have no side effects. If you want to cause a side effect in response to an action, the right place to do this is in the potentially async action creator.

:::

Arguments

  1. action (Objectโ€ ): A plain object describing the change that makes sense for your application. Actions are the only way to get data into the store, so any data, whether from the UI events, network callbacks, or other sources such as WebSockets needs to eventually be dispatched as actions. Actions must have a type field that indicates the type of action being performed. Types can be defined as constants and imported from another module. It's better to use strings for type than Symbols because strings are serializable. Other than type, the structure of an action object is really up to you. If you're interested, check out Flux Standard Action for recommendations on how actions could be constructed.

Returns

(Objectโ€ ): The dispatched action (see notes).

Notes

โ€  The โ€œvanillaโ€ store implementation you get by calling createStore only supports plain object actions and hands them immediately to the reducer.

However, if you wrap createStore with applyMiddleware, the middleware can interpret actions differently, and provide support for dispatching async actions. Async actions are usually asynchronous primitives like Promises, Observables, or thunks.

Middleware is created by the community and does not ship with Redux by default. You need to explicitly install packages like redux-thunk or redux-promise to use it. You may also create your own middleware.

To learn how to describe asynchronous API calls, read the current state inside action creators, perform side effects, or chain them to execute in a sequence, see the examples for applyMiddleware.

Example

js
import { createStore } from 'redux'
const store = createStore(todos, ['Use Redux'])

function addTodo(text) {
  return {
    type: 'ADD_TODO',
    text
  }
}

store.dispatch(addTodo('Read the docs'))
store.dispatch(addTodo('Read about the middleware'))

 

subscribe(listener)

Adds a change listener. It will be called any time an action is dispatched, and some part of the state tree may potentially have changed. You may then call getState() to read the current state tree inside the callback.

You may call dispatch() from a change listener, with the following caveats:

  1. The listener should only call dispatch() either in response to user actions or under specific conditions (e.ย g. dispatching an action when the store has a specific field). Calling dispatch() without any conditions is technically possible, however it leads to an infinite loop as every dispatch() call usually triggers the listener again.

  2. The subscriptions are snapshotted just before every dispatch() call. If you subscribe or unsubscribe while the listeners are being invoked, this will not have any effect on the dispatch() that is currently in progress. However, the next dispatch() call, whether nested or not, will use a more recent snapshot of the subscription list.

  3. The listener should not expect to see all state changes, as the state might have been updated multiple times during a nested dispatch() before the listener is called. It is, however, guaranteed that all subscribers registered before the dispatch() started will be called with the latest state by the time it exits.

It is a low-level API. Most likely, instead of using it directly, you'll use React (or other) bindings. If you commonly use the callback as a hook to react to state changes, you might want to write a custom observeStore utility. The Store is also an Observable, so you can subscribe to changes with libraries like RxJS.

To unsubscribe the change listener, invoke the function returned by subscribe.

Arguments

  1. listener (Function): The callback to be invoked any time an action has been dispatched, and the state tree might have changed. You may call getState() inside this callback to read the current state tree. It is reasonable to expect that the store's reducer is a pure function, so you may compare references to some deep path in the state tree to learn whether its value has changed.

Returns

(Function): A function that unsubscribes the change listener.

Example

js
function select(state) {
  return state.some.deep.property
}

let currentValue
function handleChange() {
  let previousValue = currentValue
  currentValue = select(store.getState())

  if (previousValue !== currentValue) {
    console.log(
      'Some deep nested property changed from',
      previousValue,
      'to',
      currentValue
    )
  }
}

const unsubscribe = store.subscribe(handleChange)
unsubscribe()

 

replaceReducer(nextReducer)

Replaces the reducer currently used by the store to calculate the state.

It is an advanced API. You might need this if your app implements code splitting, and you want to load some of the reducers dynamically. You might also need this if you implement a hot reloading mechanism for Redux.

Arguments

  1. nextReducer (Function) The next reducer for the store to use.

File: docs/api/utils.md


id: utils title: Additional Utilities hide_title: true

 

Utility Functions

The Redux core exports additional utility functions for reuse.

`isAction`

Returns true if the parameter is a valid Redux action object (a plain object with a string type field).

This also serves as a TypeScript type predicate, which will narrow the TS type to Action<string>.

`isPlainObject`

Returns true if the value appears to be a plain JS object.