Why React projects still use Redux
Published: 2020-08-08 18:55:31

---
title: Why React projects still use Redux
description: Learn why React projects are still using Redux in 2020
canonical_url: https://blog.alexandrudanpop.dev/posts/why-react-projects-still-use-redux-in-2020-395p/
---

There has been a lot of talk lately of why Redux is not a good option anymore for state management, and why we should use hooks & the React Context API. 

As a Redux user, I want to settle the war between Context API & Redux. So let the battle start! ⚔️

{% twitter 1291754382372077570  %}

## Why Redux 
Redux got popular for a few reasons: 
- easy to test
- unidirectional data flow makes it deterministic
- state is read-only
- changes are made with pure functions
- huge ecosystem

![redux unidirectional data flow](https://dev-to-uploads.s3.amazonaws.com/i/hjn86kmzl000vpemvrmg.gif)

The problem Redux wanted to solve is **predictable state updates**. Knowing where and why the state changes and having a "single source of truth" can be an advantage. 

I personally think the biggest advantage is *testability*.

**Big apps are constructed on top of lots of tests.** 🤓

When applications grow past a certain size, it is pretty obvious no engineer will know exactly what all modules & tiny pieces do. 

That's where tests come into place. Tests are the foundation of good software. And Redux code is very easy to test.  

Redux proved to be battle-tested in big React apps. Those apps will be around for a long time and continue to use it. Almost half of React apps use Redux (according to [polls and dev surveys](https://tsh.io/state-of-frontend/#frameworks)) - so you can probably figure out why it's so popular & unpopular at the same time.

## The Redux ecosystem
Redux has a large ecosystem of tools and nice things that can help developers do other things than state management. This is a shortlist, for a more extensive one [look here](https://redux.js.org/introduction/ecosystem).
### Debugging
- [redux devtools](https://github.com/reduxjs/redux-devtools)
- [redux-logger](https://github.com/LogRocket/redux-logger)

### Side effects
- [redux thunk](https://github.com/reduxjs/redux-thunk) - for async state handling 
- [redux saga](https://redux-saga.js.org/) - awesome for complex async flows, based on ES6 generators
- [redux observable](https://github.com/redux-observable/redux-observable) -RxJS-based middleware for Redux
- [redux persist](https://github.com/rt2zz/redux-persist) - pretty much as the name states - persists the stores so you don't need to load everything again next time the user will refresh the app - making it an offline-first app

### Integrations
- [redux socket.io](https://github.com/itaylor/redux-socket.io) - for using the popular socket.io realtime communication library
- [redux react firebase](https://github.com/tiberiuc/redux-react-firebase) - firebase integration

And [many, many others...](https://redux.js.org/introduction/ecosystem).

## What to consider if using Redux
### Beware of anti-patterns: 
🐛 making global state out of state that should have been local

For example, making form data global - that's just silly. The form data has no value after it is submitted to the server.

{% twitter 1241756566048694272 %}

🐛 server state - think if what you are storing is just server state instead of global application state, and in those cases consider solutions as [react-query](https://react-query.tanstack.com/) or [swr](https://swr.vercel.app/). Those tools have things like Auto Caching + Refetching built-in.

🐛 State duplication - this is a general state management problem. You should avoid duplicating state if possible and instead derive it where needed.

🐛 Doing state updates outside the reducer
Don't do this:
```js
const initialState = {
  complexObjectArray: []
}

const badPracticeReducer = (state = initialState, action) => {
  switch(action.type) {
    case "UPDATE": return {...state, ...action.payload}

    default: return state;
  }
}

const nextState = badPracticeReducer(initialState, {
  type: "UPDATE",
  payload: someArray.map(createComplexObject)
})
```

### Learn best practices
An exhaustive list of Redux best practices and things to avoid can be found [here](https://redux.js.org/style-guide/style-guide) - compiled by the Redux maintainers.

## Should you learn Redux in 2020? 
**Yes** - if you want a React job it's a 50-50 chance that the company you go to uses Redux for its product. 

But not just because of that - the concepts that Redux became popular for - unidirectional data flow, pure functions, immutable state updates are still worth learning and will make you a better software engineer. 🌟

## What about Context API?
While I was also advocating for the Context API for new applications, I am not doing it because I don't like Redux or I don't acknowledge the benefits of using Redux. 

{% twitter 1288077056711024641 %} 

I am simply advocating for the solution that will have less complexity for new developers. Using Context API is easier than Redux because it will always go together with hooks that you already know like `useState` or `useReducer`. 

Redux adds an extra layer of complexity to our application that we carefully need to weight. 

## Conclusion

I would say **Redux** is a good candidate for applications of high complexity. Also when the libraries in the Redux ecosystem make sense (for example - if sagas make it easier to reason about complex async flows). 

When working with people newer to the React ecosystem and you don't really need the things from the Redux ecosystem I would go with **Context API**.