updated December 21, 202489 views

Chào các bạn! Hôm nay, tôi sẽ chia sẻ một thủ thuật nhỏ nhưng hữu ích trong React: tạo một custom hook để chèn file JavaScript một cách linh hoạt. Việc này rất hữu ích khi bạn cần tích hợp các thư viện bên ngoài hoặc các đoạn mã tùy chỉnh vào ứng dụng React của mình.

Đôi khi, chúng ta cần chèn một file JavaScript vào trang web, ví dụ như để sử dụng một thư viện của bên thứ ba hoặc để thực hiện một số thao tác đặc biệt. Trong React, việc này có thể được thực hiện bằng cách tạo một thẻ <script> trong DOM. Tuy nhiên, việc quản lý việc chèn script một cách thủ công có thể trở nên phức tạp, đặc biệt là khi bạn cần chèn script một cách động dựa trên trạng thái của ứng dụng.

Giải pháp: useInjectScript Hook

Để giải quyết vấn đề này, chúng ta có thể tạo một custom hook có tên là useInjectScript. Hook này sẽ chịu trách nhiệm chèn script vào DOM một cách an toàn và hiệu quả.

import { useEffect } from 'react';

export const useInjectScript = (src) => {
  useEffect(() => {
    // Kiểm tra xem script đã được chèn hay chưa để tránh chèn nhiều lần
    if (document.querySelector(`script[src="${src}"]`)) {
      return;
    }

    const script = document.createElement('script');
    script.src = src;
    script.async = true; // Sử dụng async để tải script không đồng bộ, cải thiện hiệu suất
    script.onerror = () => {
      console.error(`Failed to load script: ${src}`);
      script.remove(); // Xóa script nếu tải lỗi
    };

    document.body.appendChild(script);

    // Cleanup function (chạy khi component unmount hoặc src thay đổi)
    return () => {
      const existingScript = document.querySelector(`script[src="${src}"]`);
      if (existingScript) {
        existingScript.remove();
      }
    };
  }, [src]); // Dependency array chứa src, hook sẽ chạy lại nếu src thay đổi
};

Giải thích code

  • useEffect Hook: Chúng ta sử dụng useEffect để thực hiện việc chèn script. useEffect sẽ chạy sau mỗi lần render của component.
  • Kiểm tra script đã tồn tại: Đoạn code sau sẽ kiểm tra xem script với src đã được chèn vào DOM hay chưa. Nếu đã tồn tại, hook sẽ không làm gì cả, tránh việc chèn script nhiều lần.
    if (document.querySelector(`script[src="${src}"]`)) {
      return;
    }
  • async attribute: Thay vì defer, tôi khuyến nghị sử dụng async. async cho phép script được tải và thực thi bất đồng bộ, giúp cải thiện hiệu suất tải trang.
  • onerror handler: Thêm xử lý lỗi onerror để bắt các trường hợp script không tải được.
  • Cleanup function: Hàm cleanup trong useEffect sẽ được gọi khi component unmount hoặc khi src thay đổi. Nó sẽ loại bỏ script khỏi DOM, tránh rò rỉ bộ nhớ.
  • Dependency array [src]: Dependency array chứa src. Điều này đảm bảo rằng useEffect sẽ chạy lại mỗi khi src thay đổi, cho phép bạn chèn các script khác nhau một cách động.

Cách sử dụng

Để sử dụng hook useInjectScript, bạn chỉ cần import nó vào component của bạn và gọi nó với đường dẫn đến file script.

import { useInjectScript } from 'components/useInjectScript';

const MyComponent = () => {
  useInjectScript('https://example.com/my-script.js'); // Thay thế bằng đường dẫn script của bạn

  return (
    <div>
      {/* Nội dung component */}
      <h1>Hello World</h1>
    </div>
  );
};

export default MyComponent;

Ưu điểm của việc sử dụng hook

  • Tái sử dụng: Bạn có thể sử dụng hook này trong bất kỳ component nào.
  • Dễ dàng quản lý: Việc chèn script được quản lý một cách tập trung trong hook.
  • Tránh chèn script nhiều lần: Hook tự động kiểm tra xem script đã được chèn hay chưa.
  • Cleanup: Hook tự động loại bỏ script khi component unmount, tránh rò rỉ bộ nhớ.
  • Tối ưu hiệu năng: Sử dụng async giúp tải script bất đồng bộ.

Kết luận

useInjectScript là một custom hook đơn giản nhưng mạnh mẽ, giúp bạn quản lý việc chèn script trong React một cách hiệu quả. Hy vọng bài viết này sẽ hữu ích cho các bạn. Nếu có bất kỳ câu hỏi nào, đừng ngần ngại để lại bình luận bên dưới. Cảm ơn các bạn đã theo dõi!