4 HELPFUL REDUX PRACTICES

Jackattack
The Startup
Published in
4 min readJun 14, 2020

by Jackattack

Redux is an excellent global state management library for client-side projects. Since learning Redux, I have almost always utilized it in my React projects, because it allows us to navigate around the unidirectional flow of data characteristic of React. Personally, I prefer to Redux to React’s built-in Context API because it allows us to keep our data management logic and our components separated.

To demonstrate some of these practices I’ve found helpful, I’ll give you a small window into a MERN stack application I’ve been building.

1.) redux-devtools-extension package

Using the chrome’s redux extension is profoundly helpful for debugging and managing our app’s state as it gives us direct insight into the redux store, down to the actions being dispatched, the current data in our state, and the time which it takes for particular actions to occur. Make sure you have redux-devtools-extension installed on your chrome browser. Install chrome’s redux devtools and install the redux-devtools-extension in your project.

When we create our store, we’ll use the composeWithDevTools method from the package and apply our thunk middleware. Redux thunk allows us to safely perform asynchronous actions such as data fetches in our redux store.

2.) Creating a separate file for action types.

This tactic I’ve found particularly helpful for debugging. Rather than call our dispatch methods with a string on each call, create a file in which we store exportable variables that hold our action types. We can then import these variables where they are needed.

Above are a series of action types I’m using throughout my project where I perform CRUD actions on the following “tables” of data. I’ve separated them in much the same way as I have their reducers separated.

I’ve made a separate directory called redux in my frontend where I store all of my various redux-related files. We can now import our actions to perform dispatch calls to ultimately pour data into the redux store.

For instance, let’s walk through how state of our categories is being managed. In my actions file for categories, we import the necessary types from the types file, and call them when we’re making dispatches to the store.

Then, in the categories reducer, we listen for those action types and save data accordingly.

Rather than write out strings, we use variables, which allows for cleaner code and ultimately a lesser likelihood of bugs and much, much better organization. In fact, I generally recommend storing strings that will be repeatedly used in variables for easier to read and cleaner code. The fewer strings, the better if you ask me. :)

3. async…await

While this is not fundamentally a Redux-related concept, I cannot recommend using it because it makes asynchronous operations look synchronous. Rather than chain .then’s and maybe a .catch method, we can use a try…catch block to catch any errors raised in the execution of our asynchronous code. In our actions, we can store those caught errors in state to display to ultimately lead to a richer user experience, displaying user errors or server errors in a smooth and controlled way.

4.) Manage app’s loading state in Redux

Another tactic I’ve found to be really helpful in redux is managing the loading or loaded state of our data, so as to render certain screens only upon the successfully loading of data. This allows us to seamlessly create loading docks, which ultimately bolsters the user experience of our app. Perhaps one call to a third party may take longer than another or perhaps the user’s service is suddenly slower. Implement conditionally component renders depending on whether data has been loaded or not will make our app easier to understand and use by its users. In our addCategory method from the image above, before making a call to the backend, we call a dispatch called Category_Loading, which sets loading to true in our category reducer. When the data is loaded and we dispatch our new category and add it to the reducer, we set loading to false. Now, within our components we can only render the new data when it is loaded! In my app, I haven’t yet added a conditional loading feature, but I know it’ll be very easy to implement.

You may notice I’m doing something pretty naughty in my useEffect when I call my getCategories() method if categories is empty. This is merely a screenshot I took while working through something particularly in this component and has since been fixed. ;)

--

--