This blog assumes you know how to use Redux and context API. And only want to know the differences between the two.
The why part will be brief cause I don't want this to become 3 blogs jammed into one but if you want more on why let me know.
Before I start with any new library/framework/language I like to get the answer for why it was made. So let answer that question before we get started.
why the need for redux? As you might know Redux is not a react specific library its framework agnostic. Although react community was the very first to embrace it cause it fits very nicely with the unidirectional data flow approach of reacting to change.
Redux implements the flux patter for managing state in an application and provide the state and menace to update it across the application where we need it.
Redux has 3 main components an Action a Reducer and a State
An action is just a plane object that has a type property and an optional payload by convention.
Type tells what kind of change we want and payload caries any additional data required to make that change
A reducer is a pure function that takes in the current state and computes the new state. It's just that simple.
The state is what our UI cares about we subscribe to the state or a subsection of state and update when it changes
Context API is used to share data between components in a react app and you can also share a function with which you can update the shared data.
You can use multiple contexts within the same app. Which not so each with Redux. Context API doesn't have clear instruction on how to achieve this objective. And depending upon the type of person you are you might like or dislike the hands-off approach of the context API
You might want to make a sharing strategy that best fits your application. There is no fancy chart for context API
Hey, why again. But this why is different this why is for
I mean why even ask Redux vs context. As it turns out both are solving the same problem of data sharing. But both have different pros and cons. We will rank both in three categories.
- Learning curve
- Boiler Plate code
- Performance (the most important one) ### Learning curve
context has the smother learning curve between the 2. Cause it doesn't enforce a particular way of doing things so this one goes to context
So the score is
- Redux 0
- Context 1
If you have ever read anything about Redux the only complain is the boilerplate code. so the score should be easy right? But the fact is the boilerplate is a one-time investment and it does bring a bit of structure when it comes to updating data. so let's call it even and give 0.5 to each
So the score by now is
- Redux 0.5
- context 1.5
when I say performance I not only mean run time performance but a combination of runtime and write time performance. And sometimes gain in one means loss in another so we need to have a balance.
So now its performance. I wish the answer to this one were easy, but performance depends on many factors. One of the most important ones are
- App size
- Number of visible components at a time
The TL;DR is Redux for complex apps and Context for simpler apps
I can't give a simple answer regarding whats a simple app and what a complex app. But I will try to help you make how to judge if your app is simple enough for context or complex enough for redux
Now let's try and answer when is your app simple enough for context or complex enough that Redux is needed
SO... when to use redux when is the additional complexity welcomed let dive in.
Now let's explain what the above diagram means.
I will explain it without making this post all about how redux works and how it causes react to re-render. So when using redux we can subscribe to the state or a peace/selection of the state and when the state or the selection of the state changes the subscribed component re-renders.
But what does that means? It means if your components are not subscribed to the store they won't re-render after a dispatch.
For example, Sidebar and Dashboard item is not subscribed to the store so they won't re-render when store updates simple enough
But if your component doesn't care about the part of the state that changed what then? If you see clearly we are not subscribing to the entire state but to a subset of the state (we can use the useSelection hook or connect HOC) our components will only update when the subset changes.
So now with that in mind if you have a lot of components simultaneously updating the global state where changes made by one component might not affect most of the other components. And you have lots and lots of those redux will give a performance edge (we will see why in a bit)
when to give up on redux and ignore some extra re-renders.
The same app but with context instead of redux now let's see how it will behave. When we change something in Nav the entire tree under the context provider will re-render the event if it's not using use context hook or context consumer HOC. This is indeed a performance hit and will cause unnecessary re-renders.
Now that might not a big issue depending on the app. For example, if most of the state is the local and global state is rarely updated (e.g auth state, theme state) context can be used in such a condition cause few unnecessary re-renders is not that big of an issue especially considering the ease of use and development brought by context API
About the last point as you see it not easy. So you can use the above method and see where that one point goes to for your app
The summary would be use context when the app is small and simple but redux when the app is big and complex. Well, all apps start as small and simple and grow into a bigger and complex app what to do then? Answer to that will require an article to itself