Error Handling in React 16

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