Tôi hiện đang theo dõi cùng với tài liệu React JS và tôi đã gặp phải một vấn đề với các ranh giới lỗi không hoạt động như mong đợi. Tôi đã thử sao chép ví dụ được hiển thị trong CodePen do các tài liệu cung cấp và một vài ví dụ đơn giản khác mà tôi đã tìm thấy trên internet, tuy nhiên nó không hoạt động giống như tôi trong bản demo và tôi đang vật lộn để hiểu tại sao.
Vấn đề chính xác là lỗi được ném hai lần vì thành phần BuggyCorer được hiển thị thêm thời gian. Tôi không hiểu tại sao thành phần này lại xuất hiện lần thứ hai.
Xin hãy xem ví dụ tối thiểu này.
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;
Thành phần BuggyCorer đang được thay thế bằng <p>
thẻ hiển thị Lỗi Lỗi (đây là hiệu ứng mong muốn), nhưng chỉ trong chốc lát. Ngay sau đó, trang lỗi mặc định đang được hiển thị, đánh bại mục đích của Ranh giới Lỗi.
Đây là bảng điều khiển của tôi:
Tôi sẽ đánh giá cao bất kỳ thông tin bạn có thể cung cấp về chủ đề này.
Giải quyết tạm thời:
Đây không phải là câu trả lời cho câu hỏi của tôi, nhưng một cách để ngăn chặn kết xuất không cần thiết là ném lỗi từ componentDidUpdate
thay vì 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
bạn sẽ thấy rằng nó ném lỗi hai lần, nhưng nó chỉ truyền vào componenDidCatch
một lần.