Reputation: 6027
There is something basic that I am missing, but since I didn't find it myself, I overcame my embarrassment and decided to post it here...
I expected the following code to render "Error", but not to crash afterwards. When running in chrome, however, it does crash, displaying the following:
Here is the code:
import React, { Component } from 'react';
import Child from 'components/Child';
export default class App extends Component {
constructor(props) {
super(props);
this.state = { error: null, errorInfo: null };
}
componentDidCatch(error, errorInfo) {
this.setState({
error: error,
errorInfo: errorInfo
});
console.log(`%c In App/componentDidCatch. error: ${error}, errorInfo:`, 'color: #222; background: #dfd');
console.log(this.state.errorInfo);
}
render() {
console.log(`%c In App/render. error: ${this.state.error}, errorInfo:`, 'color: #222; background: #dfd');
console.log(this.state.errorInfo);
if (this.state.error) {
return (
<div>
Error
</div>
);
}
return (
<div>
<Child />
</div>
);
}
}
import React, { Component } from 'react';
export default class Child extends Component {
render() {
throw new Error('Child crashed!');
return (
<div>
Child is here
</div>
);
}
}
Upvotes: 0
Views: 4456
Reputation: 636
To make it work you should render your Child component wrapped in App:
import React, { Component } from 'react';
export default class ParentComponent extends Component {
render() {
return (
<App>
</Child>
</App>
);
}
}
And App render method:
render() {
console.log(`%c In App/render. error: ${this.state.error}, errorInfo:`, 'color: #222; background: #dfd');
console.log(this.state.errorInfo);
if (this.state.error) {
return (
<div>
Error
</div>
);
}
return this.props.children
}
You should also consider changin the naming of your App component.
UPDATE (after discussion in comments).
You are using react-create-app
which has build in overlay to signal errors.
Read that issue for react-create-app
to learn more.
Tip: you can close this overlay with x (look for it on your site).
Upvotes: 3