When and why to use Redux?

The truth of a proper state management in React.


When it comes to the state management in React.js applications, there are a lot of myths and different opinions about it. Some people are really into Redux for managing app’s state, saying it’s the best solution out there, and the other people says the opposite. They often argue that Redux does way too much, is too big and requires you to write a lot of boilerplate code. And they also says that there are some other state management libraries, which can be used in React environment as well. On the other hand side, people prefering Redux says it can manage your application in a better way, aggregating it into one single source of truth and centralizing it. And there’s no winner there - all of this arguments are right. In this post, i’m not going to urge you to choose any of them. Instead, i’m going to dive a bit more deeply into using both of them in some cases and discuss how they can help you managing your application state. Additionally, i’ll try to explain why and when to use Redux. Happy reading!


The problem

The problem of the state management is simple, however, it grew a bit more lately. This is because with React v16.8, the core team introduced hooks. With them, we can easily access the class component features within just a standard JavaScript function. And one of the hooks we already have is useContext(). It allows you to “connect” with your Context and use it in your React component. And that started all of the discussions. This is because Redux for React also uses Context API! This time people started to think if there’s any real sense to use Redux since it’s just a Context API they can implement on their own. The answer might look simple, but it isn’t. Both Redux and Context API implements some features that can help you a lot for state management, but they’re not identical.


Context API

Context API is kind of solution for a prop drilling problem. It allows you to pass props down to make it accessible for all of the components without needing to pass all of this props on your own. And with useContext(), a lot of people detected we can easily manage our state in that way, passing all of the props from state down and access them on demand from any of the children components. Amazing! But what about state changes? Context API can also cover that, so we can pass the updating functions as well. Take a look:

An example of Context API passing the update props to the children components via useState().

You can easily do all of your state management that way, it’s totally ok, but if you’re working with a lot of state and want to make it generally more predictable, you should also take a look at useReducer() hook. It’s used to create a reducer that can dispatch your events and change the state via them. An action can be dispatched as a plain object or as an action creator (function taking an argument and returning an action based on it). Sounds familiar? This is the exact same way that Redux gives us! Take a look again:

An example of Context API passing the update props to the children components via useReducer().

You already see how convienient it can be. You can even write your own custom hook that gets the update count function from the given Context object:

An example of Context API passing the update props to the children components via useReducer() and accessing them via custom hooks.

As you can see, Context API can help us a lot when it comes to the state management. We can also more than one Context objects here. Context API is amazing!


Redux

On the other hand side, Redux does not allow us to define more than one store, because there is only one source of truth. However, we can still write some custom hooks that gets our state and updates it. Take a look at an advanced example again:

An example of Redux with custom hooks and without react-redux.

As you can see, we can still use Redux with custom hooks and even without react-redux. This is important, especially because one of the most pros of Redux is that it’s independent from any library, meaning you can use it everywhere. And - similarly to useReducer() + useContext() - we still use the same codebase here. And if we dive detaily into it, we’ll see that there are a lot of similar stuff there. Custom hooks, reducer, components and so on - it’s almost the same in both cases, in fact, in Redux’s case we use subscribe method, which is quite similar to which useCallback() does.


So when to choose Redux?

So when to choose Redux? My answer will be simple: when you really need it. Redux can be similar to React’s Context API, but they’re also some differences there. Context API for example, doesn’t allow you to use enchancers and thunks (by default, since we can achieve it in some other ways) and Redux allows you to do so. However, on the other hand side, normally we can have only one store in react-redux, but with Context, we can have a lot of them. I think it’s just up to you to choose the right one for your project and whichever you choose - you’ll choose well.


Summary

I think this article gived you an overal idea of when to use Redux and when to use Context API. Remember the technology stack is always up to you and any choose will be right and will get the state management work done very well. If you have any questions or feel something unclear, feel free to write me about it on either my Twitter, Instagram, Facebook or in the comment section below. Thank you for reading and see you next week!


“Fun fact, there’s nothing technically stopping you from writing your entire application as a single React Component. It can manage the state of your whole application and you’d have one giant render method… I am not advocating this though… Just something to think about :)” - Kent C. Dodds

That’s it for now

Jakub