What to put on the Redux state
Tags: redux, frontend
Published: 2020-05-20 20:02:51

Following up the [react](https://reactjs.org/)/[redux](https://redux.js.org/) community these past years, I've seen many inquiring whether [redux](https://redux.js.org/), or any equivalent state management solution, was even needed for achieving X or Z in a SPA. Alternatives such as using the [context API](https://reactjs.org/docs/context.html), as a simpler [redux](https://redux.js.org/) clone, or even ignoring it altogether and going for [component state](https://reactjs.org/docs/state-and-lifecycle.html) were also common place.

Being not one to favour dichotomies, I won't try to convince you that [redux](https://redux.js.org/) is the way to go, given I myself had repented over using [redux](https://redux.js.org/) for some use cases. In hindsight one of those bad decisions involved adopting [redux form](https://github.com/redux-form/redux-form) for handling form state. If you asked me, a couple years ago, had you any need to have form data in [redux](https://redux.js.org/) specifically? I certainly couldn't raise one valid point for that. Of course [redux form](https://github.com/redux-form/redux-form) API was nice and facilitated form handling, but it also created its own share of problems.

Unfortunately [react final form](https://github.com/final-form/react-final-form), [formik](https://jaredpalmer.com/formik/) and others weren't available at the time.So [redux form](https://github.com/redux-form/redux-form) just seemed right. That said I've had my own share of issues, especially when dealing with big forms. More specifically it dispatches a [redux](https://redux.js.org/) action per field registration, during initial render, which made forms with many fields feel sluggish. Still an issue present on it, which libraries relying on [component state](https://reactjs.org/docs/state-and-lifecycle.html) such as [react final form](https://github.com/final-form/react-final-form) and [formik](https://jaredpalmer.com/formik/) don't have. In fact even [redux form](https://github.com/redux-form/redux-form)'s creator recommends the use of [react final form](https://github.com/final-form/react-final-form) nowadays, if you have no need to have form data in [redux](https://redux.js.org/). It's worth mentioning that both were created by the same person.

With that I intend to exemplify that being adamant about a technical or methodological choice might cause you trouble anyway. Oh, I won't have such problems because I opted on using the [context API](https://reactjs.org/docs/context.html) instead of [redux](https://redux.js.org/), you might say. But relying on the [context API](https://reactjs.org/docs/context.html) has its drawbacks. Most noticeably the fact that any change on the value of a given context provider will trigger a re-render of its underlying component tree, even if it changes something that your component isn't even using. Of course you can have your [React.memo](https://reactjs.org/docs/react-api.html#reactmemo), [PureComponent](https://reactjs.org/docs/react-api.html#reactpurecomponent) or [shouldComponentUpdate](https://reactjs.org/docs/react-component.html#shouldcomponentupdate) life-cycle method in place, but that wouldn't be an issue with [react redux](https://react-redux.js.org/). On [react redux](https://react-redux.js.org/), assuming default behaviour, a re-render will only happen when the [shallow comparison of the returned object's fields of the mapStateToProps is true](https://react-redux.js.org/using-react-redux/connect-mapstate#return-values-determine-if-your-component-re-renders) or when the [strict equality of the returned value of the useSelector hook is true](https://react-redux.js.org/7.1/api/hooks#equality-comparisons-and-updates). So as you see [redux](https://redux.js.org/) is better optimized when it comes to avoiding re-renders, which is paramount when you are connecting components at many levels of the component tree, as you should.

For those reasons, I'd recommend the following:

- Use [redux](https://redux.js.org/) for interactions with the backend, which are tied to pages, not shareable components. Most GETs, PUTs, PATCHes and DELETEs should apply.
- Use the [context API](https://reactjs.org/docs/context.html) for global level configuration, such as styles, internationalization, authentication info, user preferences and what not.
- Use the [component state](https://reactjs.org/docs/state-and-lifecycle.html) for the kind of components that are shared across distinct pages (e.g. form handling, dialogs), even when those require backend interactions (e.g. autocomplete selects). Usually if you can't justify why you need [redux](https://redux.js.org/), that's what you need.

What's your take on it? Do you agree? Do you have your own set of guidelines? Please follow up on the comments below.