0
0
Lập trình
Flame Kris
Flame Krisbacodekiller

Biên giới lỗi trong React với TypeScript: Nâng cao hiệu quả

Đăng vào 1 tháng trước

• 4 phút đọc

Tìm Hiểu Về Biên Giới Lỗi Trong React Với TypeScript

Khi làm việc với React, chúng ta thường biết đến khái niệm biên giới lỗi (Error Boundaries) — một cách để bọc một component nhằm bắt lỗi khi render và hiển thị giao diện dự phòng. Tuy nhiên, trong các ứng dụng thực tế, cách tiếp cận "sách giáo khoa" thường không đủ. Các lỗi bất đồng bộ, sự cố theo đường dẫn, và nhu cầu ghi log đòi hỏi một cấu hình nâng cao hơn.

Trong bài viết này, mình sẽ hướng dẫn bạn một cách tiếp cận ưu tiên TypeScript để xây dựng biên giới lỗi, giúp ứng dụng React của bạn trở nên mạnh mẽ hơn, dễ dàng gỡ lỗi hơn và thân thiện với người dùng hơn.

Mục Lục

  1. Biên Giới Lỗi Được Kiểu Hóa Mạnh
  2. Biên Giới Theo Đường Dẫn: Tách Biệt Các Lỗi
  3. Xử Lý Lỗi Bất Đồng Bộ và Lỗi Sự Kiện
  4. Biên Giới Có Thể Đặt Lại: Cho Phép Người Dùng Khôi Phục
  5. Cách Tiếp Cận Tầng Bậc Để Ứng Dụng Sẵn Sàng Sản Xuất
  6. Kết Luận

1. Biên Giới Lỗi Được Kiểu Hóa Mạnh

Đầu tiên, chúng ta hãy định nghĩa một biên giới lỗi vững chắc, thân thiện với TypeScript, giúp xử lý lỗi một cách linh hoạt và ghi lại chúng:

typescript Copy
import React from "react";

interface ErrorBoundaryProps {
  children: React.ReactNode;
  fallback?: React.ReactNode;
}

interface ErrorBoundaryState {
  hasError: boolean;
  error?: Error;
}

export class AppErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {
  state: ErrorBoundaryState = { hasError: false };

  static getDerivedStateFromError(error: Error): ErrorBoundaryState {
    return { hasError: true, error };
  }

  componentDidCatch(error: Error, info: React.ErrorInfo) {
    // Ghi lại lỗi vào dịch vụ theo dõi
    console.error("Đã ghi lại lỗi:", error, info);
  }

  render() {
    if (this.state.hasError) {
      return this.props.fallback ?? <h2>Có gì đó không ổn.</h2>;
    }
    return this.props.children;
  }
}

Cấu trúc này mang lại tính an toàn về kiểu cho cả props và state trong khi giữ việc xử lý lỗi tập trung.

2. Biên Giới Theo Đường Dẫn: Tách Biệt Các Lỗi

Thay vì chỉ có một biên giới lớn ở gốc ứng dụng, hãy bọc các đường dẫn hoặc tính năng cụ thể. Cách này giúp một trang bị lỗi không làm sập toàn bộ ứng dụng:

typescript Copy
import { AppErrorBoundary } from "./AppErrorBoundary";
import Dashboard from "./Dashboard";

function DashboardRoute() {
  return (
    <AppErrorBoundary fallback={<h2>Không thể tải Dashboard.</h2>}>
      <Dashboard />
    </AppErrorBoundary>
  );
}

Người dùng vẫn có thể điều hướng ứng dụng của bạn, ngay cả khi một trang gặp lỗi.

3. Xử Lý Lỗi Bất Đồng Bộ và Lỗi Sự Kiện

Biên giới lỗi của React không bắt được lỗi trong async/await hoặc các trình xử lý sự kiện. Để khắc phục điều này, hãy bọc các hàm bất đồng bộ của bạn:

typescript Copy
function safeAsync<T extends (...args: any[]) => Promise<any>>(fn: T) {
  return async (...args: Parameters<T>): Promise<ReturnType<T>> => {
    try {
      return await fn(...args);
    } catch (err) {
      console.error("Lỗi bất đồng bộ:", err);
      throw err; // tùy chọn: để biên giới lỗi bắt nếu cần
    }
  };
}

// Sử dụng
const handleClick = safeAsync(async () => {
  throw new Error("Boom!");
});

<button onClick={handleClick}>Nhấn Tôi</button>;

Điều này đảm bảo rằng các lỗi bất đồng bộ được ghi lại và có thể được biên giới lỗi bắt nếu cần.

4. Biên Giới Có Thể Đặt Lại: Cho Phép Người Dùng Khôi Phục

Một giao diện dự phòng bị đông cứng thật khó chịu. Với react-error-boundary, bạn có thể cung cấp một nút thử lại:

typescript Copy
import { ErrorBoundary } from "react-error-boundary";

function Fallback({ error, resetErrorBoundary }: {
  error: Error;
  resetErrorBoundary: () => void;
}) {
  return (
    <div>
      <p>Có gì đó không ổn: {error.message}</p>
      <button onClick={resetErrorBoundary}>Thử lại</button>
    </div>
  );
}

<ErrorBoundary
  FallbackComponent={Fallback}
  onError={(error) => console.error("Bị bắt bởi biên giới:", error)}
  resetKeys={[/* trạng thái/props mà kích hoạt đặt lại */]}
>
  <Dashboard />
</ErrorBoundary>

Người dùng có thể khôi phục mà không cần làm mới trang.

5. Cách Tiếp Cận Tầng Bậc Để Ứng Dụng Sẵn Sàng Sản Xuất

Kết hợp những chiến lược này để có một cấu hình mạnh mẽ:

  • Biên giới toàn cục → bắt những lỗi thảm khốc.
  • Biên giới theo đường dẫn/component → tách biệt các lỗi.
  • Bọc bất đồng bộ + ghi log → ghi lại những gì React bỏ lỡ.
  • Giao diện dự phòng có thể đặt lại → cải thiện trải nghiệm người dùng.

Cách tiếp cận nhiều tầng này giữ cho ứng dụng của bạn mạnh mẽ và người dùng của bạn hài lòng.

Kết Luận

Các biên giới lỗi tích hợp sẵn của React chỉ là bước khởi đầu. Trong các ứng dụng thực tế, bạn cần một chiến lược nhiều tầng, ưu tiên TypeScript:

  • Kiểu mạnh mẽ để đảm bảo an toàn
  • Ghi log để theo dõi
  • Tách biệt để đáng tin cậy
  • Khôi phục để nâng cao trải nghiệm người dùng

Bằng cách này, lỗi không còn là rào cản — chúng chỉ là một phần của hệ thống có thể quản lý.

Nếu bạn thấy bài viết này hữu ích, hãy xem thêm các bài viết khác của tôi để biết thêm về các mẫu nâng cao, sẵn sàng sản xuất.

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào