When to Move State Up to the Redux Level

Feb 2017

Something that took me a little while to hash out internally when I first started using Redux was a process from which I could derive a consistent answer to when to move some local component-scoped React state up to the Redux level (or equally, to keep some state at the component level).

Whilst the benefits of a state’s belonging to the Redux level are myriad (beyond superficial qualms such as objections to having to write more boilerplate code), are there occasions when keeping some state local in beneficial, and if so, what?

Its many multi-faceted benefits aside (such as the ability to write useful tests easily, how usefully it plays with server-side rendering, etc.), the big praise for it comes in the ease with which developers can reason about the flow of state using simple primitives in the form of single-purpose ‘actions’ and structure set up explicitly to handle these individual action dispatches.

We can view Redux’s main function as a means of improving the quality of reasoning about how the value of some singular shared state changes over time within many dependant components. (For example, managing the state of whether a user is logged in or not, and the necessary many components being a function of this single state).

With the above in mind, my internal algorithm for accessing the suitability of some state’s level is something like the following, and may at the least help consideration:

  • Is state X shared by many different components? If yes, move the state to Redux and pass it down along with relevant actions as props.

  • Does each state-x-dependent component instantiation need its own disparate state X? 1 - If yes, keep the state component-scoped.

  • Are there any other consequences in my moving (or not moving) the state to Redux that would sufficiently outweigh the benefits yielded by one of the above choices? Viz. (amongst others):

    • Is the state going to need to be updated more frequently than (something like) every second? This might be performance-critical.
    • Is it possible to remove this state entirely and have it be some function of existing state?
    • Et cetera.

    This isn’t a hard and fast rule, but more a general method by which I can start thinking about state consistently. The one/many-to-one/many distinction is particularly useful as a starting point and is usually indicative as whether moving state up the tree is something suitable from the get-go.

1 (e.g. Each <Dropdown/> component may need its own state for its being ‘open’ or not).