Redux FAQ: React Redux

    React Redux

    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 official 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.

    While it is possible to write Redux store subscription 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.

    Overall, React-Redux encourages good React architecture, and implements complex performance optimizations for you. It is also kept up-to-date with the latest API changes from Redux and React.

    Further Information

    Documentation

    Why isn't my component re-rendering, or my mapStateToProps running?

    Accidentally mutating or modifying your state directly is by far the most common reason why components do not re-render after an action has been dispatched. Redux expects that your reducers will update their state “immutably”, which effectively means always making copies of your data, and applying your changes to the copies. If you return the same object from a reducer, Redux assumes that nothing has been changed, even if you made changes to its contents. Similarly, React Redux tries to improve performance by doing shallow equality reference checks on incoming props in , and if all references are the same, shouldComponentUpdate returns false to skip actually updating your original component.

    It's important to remember that whenever you update a nested value, you must also return new copies of anything above it in your state tree. If you have state.a.b.c.d, and you want to make an update to d, you would also need to return new copies of c, b, a, and state. This demonstrates how a change deep in a tree requires changes all the way up.

    Note that “updating data immutably” does not mean that you must use Immutable.js, although that is certainly an option. You can do immutable updates to plain JS objects and arrays using several different approaches:

    • Copying objects using functions like Object.assign() or , and array functions such as slice() and concat()
    • The array spread operator in ES6, and the similar object spread operator that is proposed for a future version of JavaScript
    • Utility libraries that wrap immutable update logic into simpler functions

    Further information

    Documentation

    Even though the array might contain the exact same object references each time, the array itself is a different reference, so the shallow equality check fails and React Redux would re-render the wrapped component.

    The extra re-renders could be resolved by saving the array of objects into the state using a reducer, caching the mapped array using Reselect, or implementing shouldComponentUpdate in the component by hand and doing a more in-depth props comparison using a function such as _.isEqual. Be careful to not make your custom shouldComponentUpdate() more expensive than the rendering itself! Always use a profiler to check your assumptions about performance.

    For non-connected components, you may want to check what props are being passed in. A common issue is having a parent component re-bind a callback inside its render function, like . That creates a new function reference every time the parent re-renders. It's generally good practice to only bind callbacks once in the parent component's constructor.

    Further information

    Documentation

    How can I speed up my mapStateToProps?

    While React Redux does work to minimize the number of times that your mapStateToProps function is called, it's still a good idea to ensure that your mapStateToProps runs quickly and also minimizes the amount of work it does. The common recommended approach is to create memoized “selector” functions using Reselect. These selectors can be combined and composed together, and selectors later in a pipeline will only run if their inputs have changed. This means you can create selectors that do things like filtering or sorting, and ensure that the real work only happens if needed.

    Further information

    Documentation

    If you do not provide your own mapDispatchToProps function when calling connect(), React Redux will provide a default version, which simply returns the dispatch function as a prop. That means that if you do provide your own function, is not automatically provided. If you still want it available as a prop, you need to explicitly return it yourself in your mapDispatchToProps implementation.

    Further information

    Documentation

    Should I only connect my top component, or can I connect multiple components in my tree?

    Early Redux documentation advised that you should only have a few connected components near the top of your component tree. However, time and experience has shown that such a component architecture generally requires a few components to know too much about the data requirements of all their descendants, and forces them to pass down a confusing number of props.

    The current suggested best practice is to categorize your components as “presentational” or “container” components, and extract a connected container component wherever it makes sense:

    In fact, benchmarks have shown that more connected components generally leads to better performance than fewer connected components.

    In general, try to find a balance between understandable data flow and areas of responsibility with your components.

    Further information

    Documentation