React-Redux Conditional Rendering Revisited

Hello, everyone. This is small tutorial on how to handle conditional rendering in React-Redux app for those, who have some idea what React and Redux are, but not an expert. If you are not familiar with conditional rendering, you should check out official documentation.

Almost every dynamic web application requires you to handle rendering for the time request is being made. In this article, we will discuss two ways (I’ve come up with so far) of how to do it.

The Old Way

In my React-Redux apps, I used to keep variables in my store to track the request. I use redux-thunk to dispatch asynchronous actions. So usually, my action creator will dispatch 2 actions out of 3 (depends on response) in total:

  1. One when request is about to be sent
  2. One when we receive successful response
  3. One when we receive an error

Then in reducer, I would handle those dispatches:

As you might notice, I used 3 variables to track request state. And in component, we can access them, in order to create conditional logic for rendering:

Hell yeah, we achieved our goal! However, we have to create 3 variables for each request, and also reset them once in a while. It might not be an issue for very small app, but usually number of our actions is going to grow, so the reducer will also grow. Hence, you might end up with something like this:

Let’s admit, that is hella scary reducer. And it’s also difficult to debug/use. You will have to rely on your naming skills or remember which variable utilized by which request. It is not safe either, since each smart component can access them.

The New Way

It might not be new way for experienced React developer, but we’re aiming at amateurs, just like myself. Before, we put request tracking variables into the reducer. However, rendering is UI issue, and hence should be under total responsibility of the component itself. Therefore, we can use callbacks (or promises) to handle this:

And in action creator:

As a result, our reducer will become:

Would you look at this! Our reducer got simplified and does not care about rendering UI, we shifted responsibility to the component. This way, our reducer will be more reusable and easier to use/debug, as well as variables are scoped to the component

UPD: You have to keep track of whether component is mounted or not in order to avoid bugs. One way is to have class property, which is set to true in componentDidMount() and to false in componentWillUnmount(). Other way is to use cancelable promises instead of callbacks. Further read: Thanks to Maarten Schumacher for pointing this out

If you enjoyed this story, please push ♥, so more people will be able to see it. If you have any suggestions or noticed flaws in these methods, let me know in comments section! Thank you reading it, and have a good day!