react-error-boundary an example
Tags: react
Published: 2021-04-05 19:27:24

---
title: react-error-boundary an example
published: true
description: An example of using react-error-boundary
tags: react
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/go8jdn6z5mu24eh7cu4a.jpeg
---
<small>(Photo by <a href="https://unsplash.com/@markusspiske?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Markus Spiske</a> on <a href="https://unsplash.com/?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a>)</small>

Today I used [react-error-boundary](https://www.npmjs.com/package/react-error-boundary) and thought I'd blog about it - just it's usage in a project.

Basically, I had something like the following in a component:

```jsx
        {selectIsRetryInitialDataFetchRequired(state) ? (
          <X {...propsA} />
        ) : selectIsLoginAgainRequired(state) ? (
          <X {...propsB} />
        ) : selectIsContactCustomerSupportRequired(state) ? (
          <X {...propsC} />
        ) : 
// etc... conditions to know when data loaded successfully
// render main UI
// fallback render spinner
```

The select functions are deriving values from state to know - based off of the responses of an HTTP client - what *error* UI to render (e.g. a 500 or JS fetch error in any of the requests made to get the data to be able to sensibly show the main UI would be an `isRetryInitialDataFetchRequired` of `true`).

Today I got the requirement that one of the HTTP requests being made will have another error response I'm to handle - still an error UI, but resolving it differs so it requires a different UI.

To be fair, this component (to me), is still quite easy to understand and reason about, especially since `X`, the error handling UI component is just the same component with variations on text content and button actions. The meat is in the "happy path" which brings together the main components used by the micro app (a small React app that is loaded by another app in a very specific use case).

The addition to the error UIs, though, has a little more going on and it's starting to get annoying to keep everything there.

Long story short, I ended up replacing those error branches with:

```jsx
  useErrorHandler(selectIsErrorFallbackRenderRequired(state));
```

where `selectIsErrorFallbackRenderRequired` is just a combination of the previous selectors (and soon to have another):

```js
export const selectIsErrorFallbackRenderRequired = (state) =>
  selectIsRetryInitialDataFetchRequired(state) ||
  selectIsLoginAgainRequired(state) ||
  selectIsContactCustomerSupportRequired(state);
```

`useErrorHandler` is from [react-error-boundary](https://www.npmjs.com/package/react-error-boundary). When the selector returns true, it ends up rendering its closest `ErrorBoundary`… so obviously, I also had to add one of those at the root level:

```jsx
      <ErrorBoundary
        fallback={<ErrorFallback state={state} {...otherProps} />}
        resetKeys={[selectIsErrorFallbackRenderRequired(state)]}
      >
        <App state={state} />
      </ErrorBoundary>
```

`ErrorFallback` is now responsible for rendering any error UI the micro app may have.

The `resetKeys` also gets passed `selectIsErrorFallbackRenderRequired(state)` i.e.

> From my state - calculate whether the app needs to render one of it's error UIs - and if this calculated value ever changes, reset i.e. render the `ErrorBoundary`'s children instead of the fallback.

How I'm thinking about it is - this is my way in the `ErrorFallback`:

```js
useErrorHandler(selectIsErrorFallbackRenderRequired(state));
```

… and this is my way out:

```jsx
resetKeys={[selectIsErrorFallbackRenderRequired(state)]}
```

`ErrorFallback` gets passed `state` so it can do its own selections and render appropriately.

Seems to be working so far 🙂

Apart from separation of concerns, it has the added benefit of catching errors which React's error boundaries can catch (and default to the "contact support" error UI) - not that I'm expecting that to happen with tests and Typescript thrown in the mix 😛

Kudos to [Kent C. Dodds](https://kentcdodds.com/blog) and the OS community for another great tool 👏