Replace Redux with React Hooks, the easy way.
Alessandro Annini
Posted on November 26, 2019
Photo by Omer Rana on Unsplash
Do you ever wonder if you can really replace Redux with React Hooks when it comes to the global state management of your applications, even the most complex?
It happens to me all the time I need to store some data so I decided not to wait a super-definitive opinion from the community but try firsthand.
What the hell, I should try anyway if it fits the way I work!
I love using GraphQL but, when I develop a complex application, I still need some kind of global store, so I started searching for articles about how to replace redux store with the useContext
React hook. I found a few, this one is very inspiring but I want it to be even cleaner.
The solution I want has to be:
- 🎣 using React hooks;
- 🚫 without switch statements;
- 😌 damn simple and clean;
- 🚀 damn fast to use;
- ♻️ reusable.
TLDR; This is what I got:
Woah Slow Down
Step 0
When I create the Store with Store.js i need the initialState
and the reducers
, the latter has to be defined as a single object where every single property is a reducer function:
Then createStoreProvider
high order function returns another function that has, as only parameter, the inner component for the Store provider so that you can nest in that point the components that will have access to the global state.
Step 1
The body of the second function sets up a way to retrieve and use the right reducer function from the initial reducers object and uses it with the useReducer
React hook so that every action will change the global state in its own way:
Step 2
The store context that we will use as global state will now be used as context provider; it will provides an object with 2 properties: the global state itself and a function that we will use to change the state:
And that’s it.
Github gist.
Step 3 (use it!)
When we want to use the state in a component we only need to import the created Store and read the needed property with the help of the useContext
React hook:
Destructuring the store context we can access to both the current state and the dispatch
function that can be used to send changes to our store selecting
- what to change thanks to the action type property and
- how to change state thanks to the payload property just like we used to do in redux.
⚠️ Downsides
When creating React context as global store you have to be aware that every time you update a value in the store, this will re-render every component that uses it, and this could create a huge performance problem!
Solutions
- This one is the cleaner: use multiple contexts so when you update one only the components that are actually using values from that store will re-render
- Use
useMemo
React hook, this way, you can specify, for every component using the global store, on which property change it will react. I updated the previous example for this solution:
Conclusions
I like the way it all blends in my code, it’s easy to manage, it does not need updates until I say so. It’s easy enough to rewrite if you are offline camping alone in a forest.
Redux principles are still valid with this setup:
- ✅ Single source of truth
- ✅ State is read-only
- ✅ Changes are made with pure functions
It is true that Redux has more plugins and tools but at the end of the day I think that having a simple code in the first place is the best way to start off a new project and understand what happens when it runs.
If you want a readymade, working solution for a global store using React hooks you can take a look to the following projects:
jhonnymichel / react-hookstore
A state management library for react using the bleeding edge hooks feature
🙏 Thanks to Full-Staks Magazine for helping me out with downsides!
About Me
I’m Alessandro Annini, I work at Scriby.it, my own company, offering software development and consulting services.
Originally posted on Medium
Posted on November 26, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.