How to deal with failure in Redux connect ?

Guillaume Wuip
Jul 23, 2019 · 7 min read

Redux’s connect is ubiquitous in the classic Redux/React application but its most frequent usage has one crucial flaw: it doesn’t account for errors. If connect can’t do that, how can we make sure we’re not letting our view pick up the slack for the holes in our store ?

Imagine a (React-)Redux app where you’re listing entities, in this case let’s say it’s Projects. You typically would have a component somewhere called ProjectList that renders another one called ProjectDetails.

But because your app is big and ProjectDetails uses other entities (Authors, Clients, etc.), you decide to connect ProjectDetails with your store directly.

This way, ProjectList’s only job is to pass a projectId prop to ProjectDetails. You then use the mapStateToProps of ProjectDetails to get everything it needs to render.

The simple ProjectList component that pass nothing but projectId to ProjectDetails:

The connected ProjectDetails with its mapStateToProps:

What could go wrong during a Redux connect?

Before we go any further, let’s pause a minute to look at the anatomy of a Redux connect.

This is its signature:

mapStateToProps: (state, ownProps) => stateProps

It received the state and the props passed by the component’s parent. You use it to access some parts of the state directly (bad) or via selectors (better) and then return an object that we can call stateProps. It’s the data coming from the state we want to pass to the component as props.

mapDispatchToProps: actionProps | (dispatch, ownProps) => actionProps

It’s either an object of action creators or a function that returns an object of action creators.

mergeProps: (stateProps, dispatchProps, ownProps) => finalProps

We don’t see this one a lot. Its role is to merge ownProps, stateProps and dispatchProps. If we don’t specify it, connect fallbacks to a function that returns { …ownProps, …stateProps, …dispatchProps } because most of the time this is what we want.

The danger here comes from mapStateToProps.

What happens when you’re getting an entity from the store but it’s not there? In the “perfect app” this should not happen, but sometimes you have to deal with it.

Going back to our example, you could have the Project entity from the store, but not the Client entity (race condition, bug, etc.) so the ProjectDetails component would not work.

Your view component is already developed. If you pass an undefined or empty project or client prop to your component it crashes.

Trying to make the component accept weak or empty props

We have now established that sometimes, we can have undefined or empty project props. We therefore need to update our component to handle this, right?

Let’s switch some props to optional with default values :

Hooray! No runtime error anymore!

Really? What about the default values we provided though? If the component needs to access a deep client.documents.pdfs property, do we have to build a fake Client entity ?

Moreover, by using default values we would find ourselves displaying a component with incomplete information to the user.

Or a component with an error message. That’s if we take the time to test our props in ProjectDetails.

This is not great. It’s not the role of the component to handle a missing entity in the store. A better approach would be not to render our ProjectDetails when there’s no data for this project, but a better-suited component instead.

Intermediary component that accepts either the props or a fallback state

What we want is a smart connect that can say “ok I have no data for my component, let’s not render it or render a fallback”. But connect’s API from react-redux doesn’t allow this.

We can achieve this logic with an intermediary component. It can accept 2 props:

  • componentProps. Component’s props I want to render most of the time.
  • fallbackProps. The props of a fallback component

If componentProps is there, render the component, if not, render the fallback.

Now that we have this intermediary component, we can use mergeProps to return either componentProps or fallbackProps.

Cool ! When the entity from the store is not here we now render a real error component.

Going further we could use the same logic to display two versions of the same component. Let’s say somewhere in your app you have a UserProfile component that is rewritten from scratch but you want to test the new version with your beta users only. You now have two components : UserProfileBeta and the oldUserProfile.

Going FP

The API of our intermediary component is not ideal. It doesn’t prevent us to pass two impossible states :

  • both componentProps and fallbackProps
  • none of them

Actually what we want to have is either componentProps or fallbackProps. Let’s use the Either data structure, from functional programming to rewrite our intermediary component with Typescript and the fp-ts library.

We can now rewrite our mergeProps to return a left({ message }) or a right(componentProps).


We took a moment to look at a common problem of big Redux apps : how to deal with empty or missing entities during a connect.

Updating our view components to handle those cases is not ideal because it doesn’t respect the separation of concern principle enough. It’s not the role of our views to handle errors trickling down from our Redux store. But the react-redux connect API doesn’t give us a way to fallback easily.

The solution proposed here is to use an intermediary component, called EitherComponent, to handle fallback when needed. This way we can prevent a runtime crash, track the error and display a proper fallback view to our user. We can also use this logic to display two versions of a component based on a data from the store (V2 for beta users, V1 for everyone else).

A big thanks ❤️ to all my iAdvize colleagues that helped me write this Anthony Griffon, Fhenon De Urioste, Axel Cateland, Pierre-Alexandre Gury and Benoit !

iAdvize Engineering

Publications from the iAdvize engineering team :)

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store