私は現在React JSのドキュメントをフォローしていますが、エラー境界が期待どおりに機能しないという問題が発生しました。ドキュメントで提供されているCodePenに示されている例と、インターネットで見つけた他のいくつかの簡単な例を複製してみましたが、デモと同じように機能しておらず、苦労しています理由を理解する。
正確な問題は、BuggyCounterコンポーネントが余分にレンダリングされるため、エラーが2回スローされることです。コンポーネントが2度目にレンダリングされる理由がわかりません。
この最小限の例をご覧ください。
import React, { Component } from 'react';
function App() {
return (
<ErrorHandler>
<BuggyCounter />
</ErrorHandler>
);
}
class ErrorHandler extends Component {
constructor(props) {
super(props);
this.state = {
error: false,
errorInfo: null
}
}
componentDidCatch(error, errorInfo) {
this.setState({ error, errorInfo });
}
render() {
console.log('rendering ErrorHandler. ' + (this.state.error ? "error" : "no error"));
if(this.state.error) {
return <p>Error</p>
}
return this.props.children;
}
}
class BuggyCounter extends Component {
constructor(props) {
super(props);
this.state = { counter: 0 };
}
handleClick = () => {
this.setState(({ counter }) => ({
counter: counter + 1
}));
};
render() {
console.log('rendering BuggyCounter. count: ' + this.state.counter);
if (this.state.counter === 5) {
throw new Error('I crashed!');
}
return <h1 onClick={this.handleClick}>{this.state.counter}</h1>
}
}
export default App;
BuggyCounterコンポーネントは、<p>
「エラー」(これは望ましい効果です)をレンダリングするタグに置き換えられていますが、これはほんの一瞬です。その直後、デフォルトのエラーページが表示され、エラー境界の目的が無効になっています。
これが私のコンソールです:
このトピックについて提供していただける情報があれば幸いです。
一時的な解決策:
これは私の質問への回答ではありませんが、冗長なレンダリングを防ぐ1つの方法は、componentDidUpdate
ではなくからエラーをスローすることですrender
。
render() {
console.log('rendering BuggyCounter. count: ' + this.state.counter);
return <h1 onClick={this.handleClick}>{this.state.counter}</h1>
}
componentDidUpdate() {
if(this.state.counter === 5)
throw new Error('I crashed');
}
componentDidCatch
、エラーが2回スローされますが、componenDidCatch
1回しか渡されないということです。