Error Handling in React 16
Bài đăng này đã không được cập nhật trong 3 năm
React 16 đã được release. Bắt đầu từ phiên bản này thì quá trình xử lý lỗi trong các Component
sẽ tiện lợi và tốt hơn.
Quá trình xử lý lỗi trong các phiên bản trước
Trước đây, các lỗi Javascript bên trong các Components
sẽ làm hỏng state
của component và cũng gây ra các lỗi trong quá trình render trong các component cha khác. Các lỗi này được thông báo rất khó hiểu gây ra khó khăn trong việc khắc phục. Một vấn đề khác là trong các phiên bản trước đây thì React không cung cấp cách thức để có thể bắt và xử lý lỗi và phục hồi khi xảy ra lỗi một cách rõ ràng trong Components
.
Giới thiệu về error boundaries
Để một lỗi Javascript trong một phần nhỏ của UI sẽ không phá vỡ toàn bộ ứng dụng thì trong React 16 đã giới thiệu một khái niệm mới có tên là error boundary
.
Error boundaries
là một React components để bắt tất cả các lỗi Javascript ở bất cứ vị trí nào trong cây component con, log lỗi ra console cũng như là hiển thị lên UI thay vì khiến cho toàn bộ cây component bị crash
.
Một React component trở thành error boundaries
khi trong component đó được định nghĩa phương thức mới trong vòng đời của nó có tên componentDidCatch(error, info)
. Ví dụ:
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
componentDidCatch(error, info) {
// Display fallback UI
this.setState({ hasError: true });
// You can also log the error to an error reporting service
logErrorToMyService(error, info);
}
render() {
if (this.state.hasError) {
// You can render any custom fallback UI
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
Sau đó thì bạn có thể sử dụng component này như bình thường
<ErrorBoundary>
<MyWidget />
</ErrorBoundary>
Phương thức componentDidCatch(error, info)
có cơ chế hoạt động giống khối catch
trong javascript thuần nhưng chỉ áp dụng cho component. Một điều chú ý là error boundaries
chỉ áp dụng với class component. Một điều khác là error boundaries
chỉ có tác dụng với các component con trong cây component của nó mà không thể bắt lỗi với chính component đang khai báo componentDidCatch
.
Component Stack Traces
Với React thì tất cả các lỗi xảy ra trong quá trình render ra UI đều được in ra console của môi trường phát triển(development). Ngoài thông báo của Javascript thì react còn cung cấp một stack lỗi của component. Điều này sẽ giúp cho developer biết chính xác nơi xảy ra lỗi trong cây component: Tuy nhiên, việc không cung cấp thông tin cụ thể số dòng và tên file xảy ra lỗi cũng gây khó khăn cho developer rất nhiều khi debug. Để khắc phục điều này thì ta có thể sử dụng thêm plugin trong babel configuration để hiển thị tên file và số dòng gây lỗi như hình dưới (Nếu bạn sử dụng Create New App thì đã cài đặt sẵ plugin trên)
Tại sao React không sử dụng try/catch
try / catch
sử dụng rất tốt nhưng nó lại chỉ làm việc với mã imperative :
try {
showButton();
} catch (error) {
// ...
}
Tuy nhiên, React components lại sử dụng việc khai báo các thẻ cần được render. Ví dụ
<Button />
Ngoài ra, với error boundaries
thì khi xảy ra lỗi trong hàm componentDidMount()
gây ra bởi việc setState
ở một chỗ nào đó trong cây component thì nó vẫn báo đúng vị trí phát sinh lỗi.
Kết luận
Trong bài viết trên, tôi đã trình bày cách để xử lý lỗi trong components
của React 16.
Cảm ơn mọi người đã theo dõi bài viết!
Để biết thêm thông tin các bạn có thể xem ở bài viết gốc tại: https://reactjs.org/blog/2017/07/26/error-handling-in-react-16.html
All rights reserved