 |
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 |
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
Comments
Post a Comment