Skip to content

Instantly share code, notes, and snippets.

@asmagin
Created January 18, 2019 16:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save asmagin/305d8e204dfe19cc4b9d9627f18d2fc9 to your computer and use it in GitHub Desktop.
Save asmagin/305d8e204dfe19cc4b9d9627f18d2fc9 to your computer and use it in GitHub Desktop.
SafePureComponent
import * as React from 'react';
import * as Models from './models';
export class SafePureComponent<P, S extends Models.SafePureComponentState> extends React.PureComponent<P, S> {
private hasError: boolean = false;
constructor(props: P, context?: any) {
super(props, context);
}
public componentDidMount() {
this.setState({ hasError: this.hasError });
}
public render() {
// componentDidCatch doesn't work in React 16's renderToString
// https://github.com/facebook/react/issues/10442
// Due to streaming nature of renderToString in React 16, need to wrap each render method in try/catch
try {
// Using error boundaries for client-side rendering
if (this.state && this.state.hasError) {
return this.renderErrorView();
}
return this.safeRender();
} catch (error) {
// this allows to differentiate server vs client rendering
if (typeof window !== 'undefined') {
// used to avoid side-effects via setState()
this.hasError = true;
console.error('Error inside', this.getComponentName(), 'is', error);
}
return this.renderErrorView();
}
}
// this method should be overridden in nested classes
protected safeRender(): React.ReactNode {
return (
<span dangerouslySetInnerHTML={{ __html: `<!-- Component ${this.getComponentName()} is not implemented. -->` }} />
);
}
protected renderErrorView() {
return (
<span
dangerouslySetInnerHTML={{
__html: `<!-- Error inside ${this.getComponentName()}. For more info, please, check the console."-->`,
}}
/>
);
}
protected getComponentName() {
return !!this.constructor.name ? this.constructor.name : 'component';
}
}
export interface SafePureComponentState {
hasError?: boolean;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment