-
-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* ✨ Add module export file * ✨ Add ErrorBoundary component * ✅ Add test suite * 🔧 Upgrade peerDependencies version * 🔧 Update flowconfig * 📝 Write docs
- Loading branch information
1 parent
08df796
commit cdd5d47
Showing
11 changed files
with
420 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,5 @@ | ||
[ignore] | ||
[untyped] | ||
.*/node_modules/react-native/Libraries/react-native/react-native-implementation.js | ||
|
||
[include] | ||
|
||
[libs] | ||
|
||
[lints] | ||
|
||
[options] | ||
|
||
[strict] | ||
[version] | ||
0.92.1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
node_modules | ||
*.log | ||
coverage |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,102 @@ | ||
# react-native-error-boundary | ||
|
||
[![Travis Build Status](https://img.shields.io/travis/carloscuesta/gitmoji-cli.svg?style=flat-square)](https://travis-ci.com/carloscuesta/react-native-error-boundary) | ||
[![Codecov](https://img.shields.io/codecov/c/github/carloscuesta/react-native-error-boundary.svg?style=flat-square)](https://codecov.io/gh/carloscuesta/react-native-error-boundary) | ||
[![Codeclimate](https://img.shields.io/codeclimate/maintainability/carloscuesta/react-native-error-boundary.svg?style=flat-square)](https://codeclimate.com/github/carloscuesta/react-native-error-boundary) | ||
[![Npm Version](https://img.shields.io/npm/v/react-native-error-boundary.svg?style=flat-square)](https://www.npmjs.com/package/react-native-error-boundary) | ||
[![Npm Downloads](https://img.shields.io/npm/dt/react-native-error-boundary.svg?style=flat-square)](https://www.npmjs.com/package/react-native-error-boundary) | ||
|
||
> A simple and reusable React-Native error boundary component 🐛 | ||
## Install | ||
|
||
```bash | ||
$ yarn add react-native-error-boundary | ||
``` | ||
|
||
## Usage | ||
|
||
Using this component is really simple. First you have to import the `ErrorBoundary` | ||
component. Then, you have to **wrap** it **around any component** that | ||
**could throw** an **error**. | ||
|
||
### Basic | ||
|
||
```jsx | ||
import ErrorBoundary from 'react-native-error-boundary' | ||
|
||
const App = () => ( | ||
<ErrorBoundary> | ||
<ChildrenThatCouldThrowEror /> | ||
</ErrorBoundary> | ||
) | ||
``` | ||
|
||
### Logging errors | ||
|
||
You can **log the error** by providing an `onError` function to the component. | ||
|
||
```jsx | ||
import ErrorBoundary from 'react-native-error-boundary' | ||
|
||
const errorHandler = (error: Error, stackTrace: string) => { | ||
/* Log the error to an error reporting service */ | ||
} | ||
|
||
const App = () => ( | ||
<ErrorBoundary onError={errorHandler}> | ||
<ChildrenThatCouldThrowEror /> | ||
</ErrorBoundary> | ||
) | ||
``` | ||
|
||
### Custom fallback component | ||
|
||
You can customize the appearance of the fallback component by providing the `FallbackComponent` prop. | ||
|
||
```jsx | ||
import ErrorBoundary from 'react-native-error-boundary' | ||
|
||
const CustomFallback = (props: { error: Error, resetError: Function }) => ( | ||
<View> | ||
<Text>Something happened!</Text> | ||
<Text>{props.error.toString()}</Text> | ||
<Button onPress={props.resetError} title={'Try again'} /> | ||
</View> | ||
) | ||
|
||
const App = () => ( | ||
<ErrorBoundary FallbackComponent={CustomFallback}> | ||
<ChildrenThatCouldThrowEror></ChildrenThatCouldThrowEror> | ||
</ErrorBoundary> | ||
) | ||
``` | ||
|
||
## API | ||
|
||
### `ErrorBoundary` | ||
|
||
These are the props that the `ErrorBoundary` component accepts: | ||
|
||
| Property | Type | Required | Default | Description | | ||
|-------------------|-------------------|----------|---------------------|------------------------------------| | ||
| children | `React.Children` | `true` | | Components that may throw an error | | ||
| FallbackComponent | `React.Component` | `false` | `FallbackComponent` | UI rendered when there's an error | | ||
| onError | `Function` | `false` | | Function for logging the error | | ||
|
||
### `FallbackComponent` | ||
|
||
These are the props that the `FallbackComponent` **receives**: | ||
|
||
| Property | Type | Default | Description | | ||
|------------|------------|---------|-------------------------------------| | ||
| error | `Error` | | The thrown error | | ||
| resetError | `Function` | | A function to reset the error state | | ||
|
||
## Demo | ||
|
||
<img | ||
src='https://user-images.githubusercontent.com/7629661/52532748-d8758400-2d29-11e9-80a0-15182517271c.gif' | ||
alt='react-native-error-boundary' | ||
width='358px' | ||
/> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// @flow | ||
import React from 'react' | ||
import { | ||
SafeAreaView, | ||
Text, | ||
TouchableOpacity, | ||
View | ||
} from 'react-native' | ||
|
||
import styles from './styles' | ||
|
||
type Props = { error: Error, resetError: Function } | ||
|
||
const FallbackComponent = (props: Props) => ( | ||
<SafeAreaView style={styles.container}> | ||
<View style={styles.content}> | ||
<Text style={styles.title}>{'Oops!'}</Text> | ||
<Text style={styles.subtitle}>{'There\'s an error'}</Text> | ||
<Text style={styles.error}>{props.error.toString()}</Text> | ||
<TouchableOpacity style={styles.button} onPress={props.resetError}> | ||
<Text style={styles.buttonText}>{'Try again'}</Text> | ||
</TouchableOpacity> | ||
</View> | ||
</SafeAreaView> | ||
) | ||
|
||
export default FallbackComponent |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// @flow | ||
import { StyleSheet } from 'react-native' | ||
|
||
export default StyleSheet.create({ | ||
container: { | ||
backgroundColor: '#fafafa', | ||
flex: 1, | ||
justifyContent: 'center' | ||
}, | ||
content: { | ||
marginHorizontal: 16 | ||
}, | ||
title: { | ||
fontSize: 48, | ||
fontWeight: '300', | ||
paddingBottom: 16 | ||
}, | ||
subtitle: { | ||
fontSize: 32, | ||
fontWeight: '800' | ||
}, | ||
error: { | ||
paddingVertical: 16 | ||
}, | ||
button: { | ||
backgroundColor: '#2196f3', | ||
borderRadius: 50, | ||
padding: 16 | ||
}, | ||
buttonText: { | ||
color: '#fff', | ||
fontWeight: '600', | ||
textAlign: 'center' | ||
} | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// @flow | ||
import React, { type Node, type ComponentType } from 'react' | ||
|
||
import FallbackComponent from './FallbackComponent' | ||
|
||
type Props = { | ||
children: Node, | ||
FallbackComponent: ComponentType<any>, | ||
onError?: Function | ||
} | ||
|
||
type State = { error: Error | null, hasError: boolean } | ||
|
||
class ErrorBoundary extends React.Component<Props, State> { | ||
state = { error: null, hasError: false } | ||
|
||
static defaultProps = { | ||
FallbackComponent: FallbackComponent | ||
} | ||
|
||
static getDerivedStateFromError (error: Error) { | ||
return { error, hasError: true } | ||
} | ||
|
||
componentDidCatch (error: Error, info: { componentStack: string }) { | ||
if (typeof this.props.onError === 'function') { | ||
this.props.onError.call(this, error, info.componentStack) | ||
} | ||
} | ||
|
||
resetError: Function = () => { | ||
this.setState({ error: null, hasError: false }) | ||
} | ||
|
||
render () { | ||
const { FallbackComponent } = this.props | ||
|
||
return this.state.hasError | ||
? <FallbackComponent | ||
error={this.state.error} | ||
resetError={this.resetError} | ||
/> | ||
: this.props.children | ||
} | ||
} | ||
|
||
export default ErrorBoundary |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`ErrorBoundary should catch errors set the state and render the default FallbackComponent 1`] = ` | ||
<RCTSafeAreaView | ||
emulateUnlessSupported={true} | ||
style={ | ||
Object { | ||
"backgroundColor": "#fafafa", | ||
"flex": 1, | ||
"justifyContent": "center", | ||
} | ||
} | ||
> | ||
<View | ||
style={ | ||
Object { | ||
"marginHorizontal": 16, | ||
} | ||
} | ||
> | ||
<Text | ||
style={ | ||
Object { | ||
"fontSize": 48, | ||
"fontWeight": "300", | ||
"paddingBottom": 16, | ||
} | ||
} | ||
> | ||
Oops! | ||
</Text> | ||
<Text | ||
style={ | ||
Object { | ||
"fontSize": 32, | ||
"fontWeight": "800", | ||
} | ||
} | ||
> | ||
There's an error | ||
</Text> | ||
<Text | ||
style={ | ||
Object { | ||
"paddingVertical": 16, | ||
} | ||
} | ||
> | ||
Invariant Violation: Objects are not valid as a React child (found: Error: This is a test error!). If you meant to render a collection of children, use an array instead. | ||
in View (created by View) | ||
in View (at errorBoundary.spec.js:41) | ||
in ErrorBoundary (at errorBoundary.spec.js:40) | ||
</Text> | ||
<View | ||
accessible={true} | ||
isTVSelectable={true} | ||
onResponderGrant={[Function]} | ||
onResponderMove={[Function]} | ||
onResponderRelease={[Function]} | ||
onResponderTerminate={[Function]} | ||
onResponderTerminationRequest={[Function]} | ||
onStartShouldSetResponder={[Function]} | ||
style={ | ||
Object { | ||
"backgroundColor": "#2196f3", | ||
"borderRadius": 50, | ||
"opacity": 1, | ||
"padding": 16, | ||
} | ||
} | ||
> | ||
<Text | ||
style={ | ||
Object { | ||
"color": "#fff", | ||
"fontWeight": "600", | ||
"textAlign": "center", | ||
} | ||
} | ||
> | ||
Try again | ||
</Text> | ||
</View> | ||
</View> | ||
</RCTSafeAreaView> | ||
`; | ||
|
||
exports[`ErrorBoundary should catch errors set the state render the props.FallbackComponent and call props.onError 1`] = ` | ||
<Text> | ||
Error! | ||
</Text> | ||
`; | ||
|
||
exports[`ErrorBoundary should render children when there are no errors 1`] = ` | ||
<Text> | ||
Hey! | ||
</Text> | ||
`; |
Oops, something went wrong.