-
Notifications
You must be signed in to change notification settings - Fork 475
Expand file tree
/
Copy pathErrorBoundary.js
More file actions
77 lines (73 loc) · 2.11 KB
/
Copy pathErrorBoundary.js
File metadata and controls
77 lines (73 loc) · 2.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import types from '@appbaseio/reactivecore/lib/utils/types';
import { arrayOf, object } from 'prop-types';
import React, { Component } from 'react';
import { connect } from '../../utils';
class ErrorBoundary extends Component {
state = {
error: null,
};
invokeErrorCallback() {
const error = this.state.error;
if (this.props.onError) {
this.props.onError(error, this.props.componentId);
}
}
static getDerivedStateFromError(error) {
return { error };
}
componentDidCatch() {
this.invokeErrorCallback();
}
componentDidUpdate() {
// Store error in state, since the component would be
// destroyed, and this.props.error would be empty
if (this.props.error && !this.state.error) {
// Below wouldn't result in an infinite loop.
// eslint-disable-next-line react/no-did-update-set-state
this.setState({ error: this.props.error });
}
if (this.state.error) {
this.invokeErrorCallback();
}
}
render() {
const error = this.state.error;
if (error) {
if (this.props.renderError) {
const { componentId } = this.props;
return this.props.renderError(error, componentId);
}
// You can render any custom fallback UI
return (
<div>
<h2>Error occured!</h2>
<p>{error.message}</p>
</div>
);
}
return this.props.children;
}
}
ErrorBoundary.propTypes = {
children: types.children,
// eslint-disable-next-line react/forbid-prop-types
error: object,
componentId: types.string,
componentIds: arrayOf(types.string),
renderError: types.func,
onError: types.func,
};
const mapStateToProps = (state, ownProps) => {
let listOfComponentsToSearch = Object.keys(state.error);
if (ownProps.componentIds && ownProps.componentIds.length) {
listOfComponentsToSearch = Object.keys(state.error)
.filter(componentId => ownProps.componentIds.includes(componentId));
}
const error = listOfComponentsToSearch
.map(componentId => state.error[componentId])
// Find the first non-null error
.find(e => e);
const componentId = listOfComponentsToSearch.find(id => state.error[id]);
return { error, componentId };
};
export default connect(mapStateToProps, null)(ErrorBoundary);