Where was Redux when I needed it?

Brian Diaz
5 min readJan 31, 2022

--

I just finished building My Pantry using React and Rails and was feeling pretty good! It was time to move on to my next project. I was introduced to Redux. When I found out it was for handling global state, my first thought was “Oh, like Context?” While they can both handle state that can be accessed in any component, no matter where they lie in the component tree, I did not give Redux enough credit. The FAQ in the Redux documentation and this blog discuss the differences and cases that warrant the use of each of them. In reading over both sources, I felt like I had a good grasp on when to use each of them. To summarize, Redux is useful when you have large amounts of state, that state needs to be accessed by many components in the application, and the logic to update that state may be complex. Did my most recent project, Super Movie Library(SML), need to be handled with Redux? Probably not… but My Pantry had more state and, while the logic to update that state wasn’t complex, Redux may have come in handy. But better later than never! I decided to build SML using Redux anyway so I can get some practice using it and be better prepared for when I do have to use Redux.

I know the basic idea of Redux is using a pure function, that is a function where the return value if solely determined by its input and has no side effects, to update state. This function takes the current state and an action to return an updated state. Since it takes current state and an action, it is also called a reducer. I learned this through Flatiron’s curriculum and built Redux from scratch to enhance my understanding. When using Redux with React I would have the boon of using Redux toolkit. Redux toolkit simplifies the setup needed to get Redux up and running.

My plan for SML was to use Redux to accomplish the same task I used Context for when I built My Pantry; Redux was to be used to manage and update the user state. Redux would be used when the user logged in, logged out, if the user decided to continue as a guest instead of creating an account, or toggled dark mode on or off.

Using the Redux quick start guide, I built my store with my reducer. Not much so far since I was only managing state associated with my user. This also helped with much of the setup required to get Redux running including setting up the Redux Dev tools, setting up redux-thunk to handle asynchronous actions, and (if I had multiple reducers) combining reducers.

When setting this up, it was one of the first instances where I notice the potential Redux has. As an application does grow, more reducers can be added to the store and separate files with these reducers can be easily found and maintained.

I will show my userReducer later. This is where all of my login, logout, and dark mode actions are.

In my index.js, I then wrapped my App component in the store provider, giving all children components access to the store.

Now it’s time to make my userReducer. The createSlice from Redux toolkit does so much so us. Before, without redux toolkit, state could only be copied and changed and that changed state would be returned. You should never change state. But with redux toolkit and the Immer library I don’t have to worry about being careful with mutating state.

Before, without createSlice, I also had to make our action creators. That is, write functions that returned objects with our action type and action payload. Now createSlice can do that for me too. Below is my reducer with my initial state and all of my actions.

We can now export these actions to any component to change as needed.

This is another instance where I notice the potential of Redux. Have complex logic to change your state? Now there is only one place you need to write it! You discovered an edge case where your logic doesn’t work as intended? Just change the action to accommodate the edge case! Once that is done, every component using that action will now use the updated logic. Neat!

Last part of setting up Redux for my app was using thunk to handle asynchronous tasks, namely, fetching the current user. With thunk you can now return an asynchronous function, like my fetch user function, shown below.

You can then add extra reducers to handle asynchronous actions. First, the pending state case will run, then, once the fetch has returned with a response, the fullfilled case will run. These reducers are shown below.

Now, by import the necessary reducers and the React-redux hooks, state can now be accessed(via useSelector) and updated(via useDispatch) from any component using the logic written in my userSlice file.

It reminds me of when I was first learning to cook. I would have my ingredients, start cooking, realize I have to chop something, start chopping and whatever was on the stove would start to burn. Using Redux reducers is like chopping and sorting everything beforehand so when you need it, it is ready to go! After this project, I feel more confident with using Redux and recognize how much Redux toolkit does for the developer. I only wish I had more state to manage!

The code for SML can be found on my Github here.

--

--