Skip to content

Instantly share code, notes, and snippets.

@burdiuz
Last active May 26, 2019 13:35
Show Gist options
  • Save burdiuz/b146540f7d878f3123b986e1dab23aea to your computer and use it in GitHub Desktop.
Save burdiuz/b146540f7d878f3123b986e1dab23aea to your computer and use it in GitHub Desktop.
import React, { createContext } from 'react';
import { ErrorHandler } from './withDidCatch';
const { Provider, Consumer } = createContext();
Provider.displayName = 'ErrorBoundaryContextProvider';
Consumer.displayName = 'ErrorBoundaryContextConsumer';
export const ErrorBoundaryProvider = ({ onRenderError }) => (
<Provider value={onRenderError}>{children}</Provider>
);
export const withErrorBoundary = (ChildComponent) => {
const Wrapper = (props) => (
<Consumer>
{(onRenderError) => (
<ErrorHandler onRenderError={onRenderError}>
<ChildComponent {...props} />
</ErrorHandler>
)}
</Consumer>
);
Wrapper.displayName = `withErrorBoundary(${ChildComponent.displayName || ChildComponent.name})`;
return Wrapper;
};
import React, { Component } from 'react';
import PropTypes from 'prop-types';
export class ErrorHandler extends Component {
static propTypes = {
onRenderError: PropTypes.func.isRequired,
children: PropTypes.node.isRequired,
errorViewRenderer: PropTypes.func,
};
static defaultProps = {
errorViewRenderer: undefined,
};
static getDerivedStateFromError(error) {
return { hasError: true };
}
state = { hasError: false };
componentDidCatch(error, info) {
const { onRenderError } = this.props;
if (onRenderError) {
onRenderError(error, info);
}
}
get hasError() {
return this.state.hasError;
}
reset() {
if (this.hasError) {
this.setState({ hasError: false });
}
}
render() {
const { errorViewRenderer, children } = this.props;
const { hasError } = this.state;
if (hasError && errorViewRenderer) {
return errorViewRenderer(this.props);
}
return children;
}
}
const withDidCatch = (ChildComponent, displayName = '') => {
const Wrapper = ({ onRenderError, ...props }) => (
<ErrorHandler onRenderError={onRenderError}>
<ChildComponent {...props} />
</ErrorHandler>
);
Wrapper.displayName = `withDidCatch(${ChildComponent.displayName || ChildComponent.name})`;
return Wrapper;
};
export default withDidCatch;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment