Cập nhật tháng 4 năm 2020:
Vấn đề dường như được khắc phục trong React 16.13.1 mới nhất, xem ví dụ về hộp cát này . Cảm ơn @abernier đã chỉ ra điều này.
Tôi đã thực hiện một số nghiên cứu và tôi đã tìm thấy một sự khác biệt quan trọng:
React không xử lý lỗi từ các phương thức vòng đời không đồng bộ.
Vì vậy, nếu bạn viết một cái gì đó như thế này:
componentDidMount()
{
throw new Error('I crashed!');
}
sau đó lỗi của bạn sẽ bị ràng buộc bởi lỗi liên kết và bạn có thể xử lý nó và hiển thị một thông báo duyên dáng.
Nếu chúng ta thay đổi mã như thế này:
async componentDidMount()
{
throw new Error('I crashed!');
}
tương đương với điều này:
componentDidMount()
{
return Promise.reject(new Error('I crashed!'));
}
sau đó lỗi của bạn sẽ được âm thầm nuốt . Thật xấu hổ cho bạn, Phản ứng ...
Vì vậy, làm thế nào để chúng tôi xử lý lỗi hơn? Cách duy nhất có vẻ là bắt rõ ràng như thế này:
async componentDidMount()
{
try
{
await myAsyncFunction();
}
catch(error)
{
//...
}
}
hoặc như thế này:
componentDidMount()
{
myAsyncFunction()
.catch(()=>
{
//...
});
}
Nếu chúng tôi vẫn muốn lỗi của mình đạt đến ranh giới lỗi, tôi có thể nghĩ về thủ thuật sau:
- Bắt lỗi, làm cho trình xử lý lỗi thay đổi trạng thái thành phần
- Nếu trạng thái chỉ ra lỗi, hãy ném nó từ
render
phương thức
Thí dụ:
class BuggyComponent extends React.Component {
constructor(props) {
super(props);
this.state = { error: null };
}
buggyAsyncfunction(){ return Promise.reject(new Error('I crashed async!'));}
async componentDidMount() {
try
{
await this.buggyAsyncfunction();
}
catch(error)
{
this.setState({error: error});
}
}
render() {
if(this.state.error)
throw this.state.error;
return <h1>I am OK</h1>;
}
}