fix(core): allow updates through error boundary (#2136)

This commit is contained in:
Shawn Erquhart
2019-03-02 15:26:08 -05:00
committed by GitHub
parent efa650ccf8
commit 3d98b72775
3 changed files with 38 additions and 20 deletions

View File

@ -63,7 +63,7 @@ function bootstrap(opts = {}) {
*/ */
const Root = () => ( const Root = () => (
<I18n locale={'en'} messages={getPhrases()}> <I18n locale={'en'} messages={getPhrases()}>
<ErrorBoundary> <ErrorBoundary showBackup>
<Provider store={store}> <Provider store={store}>
<ConnectedRouter history={history}> <ConnectedRouter history={history}>
<Route component={App} /> <Route component={App} />

View File

@ -46,6 +46,23 @@ const CopyButton = styled.button`
margin: 12px 0; margin: 12px 0;
`; `;
const RecoveredEntry = ({ entry, t }) => {
console.log(entry);
return (
<>
<hr />
<h2>{t('ui.errorBoundary.recoveredEntry.heading')}</h2>
<strong>{t('ui.errorBoundary.recoveredEntry.warning')}</strong>
<CopyButton onClick={() => copyToClipboard(entry)}>
{t('ui.errorBoundary.recoveredEntry.copyButtonLabel')}
</CopyButton>
<pre>
<code>{entry}</code>
</pre>
</>
);
};
class ErrorBoundary extends React.Component { class ErrorBoundary extends React.Component {
static propTypes = { static propTypes = {
children: PropTypes.node, children: PropTypes.node,
@ -64,23 +81,28 @@ class ErrorBoundary extends React.Component {
} }
shouldComponentUpdate(nextProps, nextState) { shouldComponentUpdate(nextProps, nextState) {
return ( if (this.props.showBackup) {
this.state.errorMessage !== nextState.errorMessage || this.state.backup !== nextState.backup return (
); this.state.errorMessage !== nextState.errorMessage || this.state.backup !== nextState.backup
);
}
return true;
} }
async componentDidUpdate() { async componentDidUpdate() {
const backup = await localForage.getItem('backup'); if (this.props.showBackup) {
console.log(backup); const backup = await localForage.getItem('backup');
this.setState({ backup }); console.log(backup);
this.setState({ backup });
}
} }
render() { render() {
const { hasError, errorMessage, backup } = this.state; const { hasError, errorMessage, backup } = this.state;
const { showBackup, t } = this.props;
if (!hasError) { if (!hasError) {
return this.props.children; return this.props.children;
} }
const t = this.props.t;
return ( return (
<div className={styles.errorBoundary}> <div className={styles.errorBoundary}>
<h1 className={styles.errorBoundaryText}>{t('ui.errorBoundary.title')}</h1> <h1 className={styles.errorBoundaryText}>{t('ui.errorBoundary.title')}</h1>
@ -96,19 +118,9 @@ class ErrorBoundary extends React.Component {
</a> </a>
</p> </p>
<hr /> <hr />
<h2>Details</h2> <h2>{t('ui.errorBoundary.detailsHeading')}</h2>
<p>{errorMessage}</p> <p>{errorMessage}</p>
{backup && ( {backup && showBackup && <RecoveredEntry entry={backup} t={t} />}
<>
<hr />
<h2>Recovered document</h2>
<strong>Please copy/paste this somewhere before navigating away!</strong>
<CopyButton onClick={() => copyToClipboard(backup)}>Copy to clipboard</CopyButton>
<pre>
<code>{backup}</code>
</pre>
</>
)}
</div> </div>
); );
} }

View File

@ -120,6 +120,12 @@ export function getPhrases() {
title: 'Error', title: 'Error',
details: "There's been an error - please ", details: "There's been an error - please ",
reportIt: 'report it.', reportIt: 'report it.',
detailsHeading: 'Details',
recoveredEntry: {
heading: 'Recovered document',
warning: 'Please copy/paste this somewhere before navigating away!',
copyButtonLabel: 'Copy to clipboard',
},
}, },
settingsDropdown: { settingsDropdown: {
logOut: 'Log Out', logOut: 'Log Out',