The simplest way to pass data from a parent to a child in a React Application is by passing it on to the child's props
. But an issue arises when a deeply nested child requires data from a component higher up in the tree. If we pass on the data through the props
, every single one of the children would be required to accept the data and pass it on to its child, leading to prop drilling, a terrible practice in the world of React.
To solve the prop drilling issue, we have State Management Solutions like Context API and Redux. But which one of them is best suited for your application? Today we are going to answer this age-old question!
What is the Context API?
Let's check the official documentation:
In a typical React application, data is passed top-down (parent to child) via props, but such usage can be cumbersome for certain types of props (e.g. locale preference, UI theme) that are required by many components within an application. Context provides a way to share values like these between components without having to explicitly pass a prop through every level of the tree.
Context API is a built-in React tool that does not influence the final bundle size, and is integrated by design.
To use the Context API, you have to:
-
Create the Context
const Context = createContext(MockData);
-
Create a Provider for the Context
const Parent = () => { return ( <Context.Provider value={initialValue}> <Children/> </Context.Provider> ) }
-
Consume the data in the Context
const Child = () => { const contextData = useContext(Context); // use the data // ... }
So What is Redux?
Of course, let's head over to the documentation:
Redux is a predictable state container for JavaScript apps.
It helps you write applications that behave consistently, run in different environments (client, server, and native), and are easy to test. On top of that, it provides a great developer experience, such as live code editing combined with a time-traveling debugger.
You can use Redux together with React, or with any other view library. It is tiny (2kB, including dependencies), but has a large ecosystem of addons available.
Redux is an Open Source Library which provides a central store, and actions to modify the store. It can be used with any project using JavaScript or TypeScript, but since we are comparing it to Context API, so we will stick to React-based Applications.
To use Redux you need to:
-
Create a Reducer
import { createSlice } from "@reduxjs/toolkit"; export const slice = createSlice({ name: "slice-name", initialState: { // ... }, reducers: { func01: (state) => { // ... }, } }); export const { func01 } = slice.actions; export default slice.reducer;
-
Configure the Store
import { configureStore } from "@reduxjs/toolkit"; import reducer from "./reducer"; export default configureStore({ reducer: { reducer: reducer } });
-
Make the Store available for data consumption
import React from 'react'; import ReactDOM from 'react-dom'; import { Provider } from 'react-redux'; import App from './App.jsx' import store from './store'; ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById("root") );
-
Use State or Dispatch Actions
import { useSelector, useDispatch } from 'react-redux'; import { func01 } from './redux/reducer'; const Component = () => { const reducerState = useSelector((state) => state.reducer); const dispatch = useDispatch(); const doSomething = () = > dispatch(func01) return ( <> {/* ... */} </> ); } export default Component;
That's all Phew! As you can see, Redux requires way more work to get it set up.
Comparing Redux & Context API
Context API | Redux |
---|---|
Built-in tool that ships with React | Additional installation Required, driving up the final bundle size |
Requires minimal Setup | Requires extensive setup to integrate it with a React Application |
Specifically designed for static data, that is not often refreshed or updated | Works like a charm with both static and dynamic data |
Adding new contexts requires creation from scratch | Easily extendible due to the ease of adding new data/actions after the initial setup |
Debugging can be hard in highly nested React Component Structure even with Dev Tool | Incredibly powerful Redux Dev Tools to ease debugging |
UI logic and State Management Logic are in the same component | Better code organization with separate UI logic and State Management Logic |
From the table, you must be able to comprehend where the popular opinion Redux is for large projects & Context API for small ones come from.
Both are excellent tools for their own specific niche, Redux is overkill just to pass data from parent to child & Context API truly shines in this case. When you have a lot of dynamic data Redux got your back!
So you no longer have to that guy who goes:
Wrapping Up
In this article, we went through what is Redux and Context API and their differences. We learned, Context API is a light-weight solution which is more suited for passing data from a parent to a deeply nested child and Redux is a more robust State Management solution.
Happy Developing!
Finding personal finance too intimidating? Checkout my Instagram to become a Dollar Ninja
Thanks for reading
Need a Top Rated Front-End Development Freelancer? Contact me on Upwork
Want to see what I am working on? Check out my GitHub
I am a freelancer who will start off as a Digital Nomad in mid-2022. Want to catch the journey? Follow me on Instagram
Follow my blogs for Weekly new Tidbits on Dev
FAQ
These are a few commonly asked questions I get. So, I hope this FAQ section solves your issues.
-
I am a beginner, how should I learn Front-End Web Dev?
Look into the following articles: Would you mentor me?
Sorry, I am already under a lot of workload and would not have the time to mentor anyone.Would you like to collaborate on our site?
As mentioned in the previous question, I am in a time crunch, so I would have to pass on such opportunities.
Connect to me on
Oldest comments (37)
You are referring to a style of Redux there that is not the recommended style of writing Redux for over two years now. Modern Redux looks very differently and is about 1/4 of the code. It does not use switch..case reducers, ACTION_TYPES or createStore and is a lot easier to set up than what you are used to.
I'd highly recommend going through the official Redux tutorial and maybe updating this article afterwards.
Thanks for pointing it out, please take a look now
Its great to have one of the creators of Redux reviewing my article!
Now the Redux portion looks okay for me - as for the comparison, I'd still say it doesn't 100% stand as the two examples just do very different things - the Context example only takes
initialValue
from somewhere and passes it down the tree, but you don't even have code to change that value ever in the future.So if you add code for that (and also pass down an option to change that data), you will probably already here get to a point where the Context is already more code than the Redux solution.
I'm not entirely sure whether I agree on this point. Using context with data update would only take 4 more lines:
useState
in the ParentinitialValue
In the end, it usually ends up as quite some more code - see kentcdodds.com/blog/how-to-use-rea... for example.
But just taking your examples side by side:
That in the end leaves the
configureStore
call - and that are three lines. You will probably save more code by usingcreateSlice
vs manually writing a Provider.But I had added the Provider in the Context example 😐
You are talking about using
useReducer
hook with the Context API. I am suggesting that if one is required to modify the data, one should definitely opt for Redux. In case only sharing the data with the Child Components is required, Context would be a better solutionYeah, but you are not using the
Parent
anywhere, which is kinda equivalent to using theProvider
in Redux, kinda making it look like one step less for Context ;)As for the "not using
useReducer
" - seems like I read over that - in that case I 100% agree. :)"I am suggesting that if one is required to modify the data, one should definitely opt for Redux." - can you elaborate? What specific advantages Redux has over using reducers with
useReducer
in React? Thanks!@gottfried-dev The problem is not
useReducer
, which is great for component-local state, but Context, which has no means of subscribing to parts of an object, so as soon as you have any complicated value in your context (which you probably have if you need useReducer), any change to any sub-property will rerender every consumer, if it is interested in the change or not.I myself really don't like using redux toolkit. Feel like I have more control when using the old way
Which part of it exactly is taking control away?
Oh, btw.: if it is only one of those "I need the control only 10% of the time" cases - you can always mix both styles. RTK is just Redux, there is absolutely no magic going on that would prevent a mix of RTK reducers and hand-written reducers.
Also, if you need to maintain some sort of complex state for any mid-level project, you can still create your own reducer using React's Context API itself, before reaching out for redux and adding external dependencies to your project initially.
But you might take a performance hit. Redux seems to be better performance-wise when you intend to update the shared data a lot - see stackoverflow.com/a/66972857/7677851.
If used correctly that is.
dev.to/mohitm15/starting-with-reac...
I found Redux to be easier to setup and work with than Context API. I migrated a library I was building in Redux to context API and reused most of the reducer logic, but the amount of optimization and debugging I had to do to make the same functionality work was a nightmare in Context. It made me appreciate Redux more and I switched back to save time. It was a good learning to know the specific use case and limitations of context.
I too am a huge fan of redux for most projects!
I hate redux, It is very complicated
Try Teaful github.com/teafuljs/teaful 😊
Referring to your example, I can write a blog post, too:
Context API vs. ES6 import
Context API is too complicated. I can simply
import MockData from './mockData'
and use it in any component. Context API has 10 lines,import
only 1 line.Then you can write another blog post
Redux vs. ES6 import
.There are maybe projects which
And then there are devs reading blogs about using redux is too complicated and end up introducing their own concepts and ideas around the Context API without knowing one thing about immutable data optimizations and so on.
You can use a react context to solve problems that are also being solved by redux, but some features and optimizations are not that easy for homegrown solutions. I mean try it out - it's a great exercise to understand why you should maybe use redux in your production code or stick to a simpler solution that has less features at all.
I'm not saying, that you should use redux in every project, but redux is not just some stupid boilerplate around the Context API => if you need global state utils check out the libs built for it. There are also others than redux.
I compared the two 3 years ago. At that moment Context API was still new but obviously the winner IMO.
Redux used to be my first choice for large applications but these days I much prefer to use the Context API. Still good to know Redux though just in case and many projects and companies still require you to know it.
try to take a look at this
github.com/priolo/jon
Context: Specifically designed for static data, that is not often refreshed or updated.
Redux: Works like a charm with both static and dynamic data.
I've working on a complex project only with context, I didn't see this point. Simply using getters and setters (it's the same thing that use useState) in context do all the work. Integrates very well with hooks and custom hooks and also easy to read.
Can you explain why redux it's better at this point?
If you work on a huge project (where you are new to the codebase) with context, you will be running up & down the Dom to find the origin of the data