Get #Amazon #Prime for this #holiday #amazonprime #christmas #2019

#Reactjs - What are React Error Boundaries?

React Error Boundaries
React Error Boundaries

When I was running some Jest tests, I got a suggestion on using react-error-boundaries.
It is similar to JavaScript catch blocks but it is for React components starting from React 16.
It is used to handle an error in JavaScript that break the UI rendering of the app.

Taken from the document:
Error boundaries are React components that catch JavaScript errors anywhere in their child component tree, log those errors, and display a fallback UI instead of the component tree that crashed.

By we define componentDidCatch function in a component, that component can act as an error boundary / 'catcher'

componentDidCatch(error, info)

Taken from the document:

componentDidCatch(error, info) {
  
  /*
     info is an object with componentStack key
     Example stack information:
     in ComponentThatThrows (created by App)
     in ErrorBoundary (created by App)
     in div (created by App)
     in App
  */
  logComponentStackToMyService(info.componentStack);
}

How to use it? Taken from the document:
Regarding the error reporting service, I have used sentry before. It reports errors happening in your app installed on your users' devices. 

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  componentDidCatch(error, info) {
    // Display fallback UI
    this.setState({ hasError: true });
    // You can also log the error to an error reporting service
    logErrorToMyService(error, info);
  }
  render() {
    if (this.state.hasError) {
      // You can render any custom fallback UI
      return <h1>Something went wrong.</h1>;
    }
    return this.props.children;
  }
}


<ErrorBoundary>
  <MyWidget />
</ErrorBoundary>

And, this was how I noticed react-error-boundaries:

React Error Boundaries suggestion
React Error Boundaries suggestion


ParkingSpotDetail Component
import React, { Component } from 'react'
import { Text, ScrollView, View } from 'react-native'
import styles from './ParkingSpotDetailStyles'
import IconWithText from '..././../../components/IconWithText/IconWithText'

export default class ParkingSpotDetail extends Component {

  constructor(props) {
    super(props)
    this._presentRate = this.props.presentRateText
    this._hourCount = this.props.presentTimeLimitText && this.props.presentTimeLimitText.startsWith('no') ?
      'There is no time limit.' : `Time limit is ${this.props.presentTimeLimitText}.`
  }

  render() {
    return (
      <ScrollView style={styles.container}>
        <View>
          <IconWithText
            icon='money'
            message={`It is ${this._presentRate} now.`}
          />
          <IconWithText
            icon='hourglass-start'
            message={this._hourCount}
          />
        </View>
        <Text
          allowFontScaling={true}
          style={styles.detailText}>{this.props.calloutDetail}</Text>
      </ScrollView>
    )
  }
}

ParkingSpotDetail snapshot test

import 'react-native'
import React from 'react'
import ParkingSpotDetail from '../ParkingSpotDetail'

// Note: test renderer must be required after react-native.
import renderer from 'react-test-renderer'

describe('<ParkingSpotDetail />', () => {
  it('ParkingSpotDetail renders correctly', () => {
    const parkingSpotDetailComponent = renderer.create(
      <ParkingSpotDetail/>
    ).toJSON()
    expect(parkingSpotDetailComponent).toMatchSnapshot()
  })
})

I need to check to make sure this.props.presentTimeLimitText  exists like the following:
this._hourCount = this.props.presentTimeLimitText && this.props.presentTimeLimitText.startsWith('no') ?
      'There is no time limit.' : `Time limit is ${this.props.presentTimeLimitText}.`

Thank you for reading!

Jun