Sử dụng useCallback thao tác với DOM element?

Trong React Funtional components khi cần làm việc với DOM element có thể bạn nghĩ ngay đến useRef, trong bài viết này mình chia sẽ bạn một cách khác “lạ à nha” với useCallback Giới thiệu sơ về useCallback Chúng ta nghe nói rất nhiều rằng bạn nên sử dụng useCallback để cải thiện hiệu

Trong React Funtional components khi cần làm việc với DOM element có thể bạn nghĩ ngay đến useRef, trong bài viết này mình chia sẽ bạn một cách khác “lạ à nha” với useCallback😱

Giới thiệu sơ về useCallback

Chúng ta nghe nói rất nhiều rằng bạn nên sử dụng useCallback để cải thiện hiệu suất trong quá trình render của React functional components.

Trong bài viết này chúng ta sẽ tìm hiểu thêm một chức năng khác khi thao tác với DOM element, tài liệu chỉ được đề cập nhẹ trong phần FAQ. How can I measure a DOM node?
.
React sẽ gọi callback ref khi mà DOM element được mount vì vậy cách này hữu ích khi cần lấy kích thước (dimensions) của DOM. Và nó cũng sẽ thay thế được useRefuseEffect như cách thông thường.
Thật ra nó chính là “callback refs” khi mà chúng ta sử dụng trong Class Components.

Lấy ví dụ

Sử dụng thư viện Chart.js để vẽ một Line Chart với data mẫu trong React Component.

Với useRef()

Đây là đoạn mã khi chúng ta áp dụng thông thường:

import{ Chart }from"chart.js";functionApp(){const ref = useRef<HTMLCanvasElement |null>(null);useEffect(()=>{const myChart =newChart(ref.current!,{
      type:"line",
      data: chartData
    });return()=>{
      myChart.destroy();};},[]);return(<divclassName="App"><h1>Implement Chart.js with useRef()</h1><canvasref={ref}style={{ height:400}}/></div>);}

Xem demo, nó rất không có gì là bất bình thường cả. Chỉ là với useCallback sẽ gọn hơn khi vừa phải useRefuseEffect xem tiếp dưới.

Với useCallback()

Đây là đoạn mã mà quê chung tôi hay dùng:

functionApp(){const ref =useCallback(async(node)=>{const{ Chart }=awaitimport("chart.js");if(node instanceofHTMLCanvasElement){newChart(node,{
        type:"line",
        data: chartData
      });}},[]);return(<divclassName="App"><h1>Implement Chart.js with useCallback()</h1><canvasref={ref}style={{ height:400}}/></div>);}

Xem demo, chú ý đoạn mã không bao gồm quá trình dọn dẹp chart 😶
Với ví dụ trên chúng ta không thực sự thấy useCallback có giá trị gì nhiều. Hãy thử đổi bài toán khác để tăng độ khó của game.

Sử dụng Intersection Observer khi scroll tới DOM element thì hãy bắt đầu vẽ chart?

import{ useInView }from"react-intersection-observer";functionApp(){const{ ref: inViewRef, inView: showChart }=useInView({
    triggerOnce:true});const ref =useCallback(async(node)=>{const{ Chart }=awaitimport("chart.js");if(node instanceofHTMLCanvasElement){newChart(node,{
        type:"line",
        data: chartData
      });}},[]);return(<divclassName="App"><h1>Lazy load Chart.js with useCallback() when they come into the viewport</h1><div>
        Lorem, ipsum dolor sit amet consectetur....
      </div><sectionref={inViewRef}style={{ height:400}}>{showChart &&<canvasref={ref}/>}</section><div>
        Lorem ipsum dolor sit am....
      </div></div>);}

Xem demo, chú ý chúng ta vẫn có nhiều cách để làm được điều trên trong đó chỉ cần tách ra một component < MyChart /> là giải pháp tối ưu nhất xem demo.

Vậy vì sao chọn useCallback?

Vậy lý do gì để lựa chọn useCallback như là một sự thay thế:

  • Hữu ích nhất khi cần tính toán kích thước (dimensions) của DOM, ví dụ như: witdth, height, offsetTop, …vv bởi vì ref value sẽ không lắng nghe khi có thay đổi giá trị.
  • Dễ hơn khi sử dụng Dynamic import() tối ưu hóa Code-Splitting giảm bundle tải gói, để ý dòng await import("chart.js")
  • Hợp lý khi DOM element có điều kiện render. Ví dụ:
    {showChart &&<canvasref={ref}/>}
  • Tôi thích thế vì nó ngầu 🤠

Kết luận

Sau tất cả useCallback chỉ là một cách tiếp cận khác thi thao tác với DOM element và là “callback refs” trong Class Components vì vậy nó cũng không có gì xa lạ. Biết đâu qua bài này bạn nhận ra trước giờ mình cũng méo dùng “callback refs”🤓

Nguồn: viblo.asia

Bài viết liên quan

WebP là gì? Hướng dẫn cách để chuyển hình ảnh jpg, png qua webp

WebP là gì? WebP là một định dạng ảnh hiện đại, được phát triển bởi Google

Điểm khác biệt giữa IPv4 và IPv6 là gì?

IPv4 và IPv6 là hai phiên bản của hệ thống địa chỉ Giao thức Internet (IP). IP l

Check nameservers của tên miền xem website trỏ đúng chưa

Tìm hiểu cách check nameservers của tên miền để xác định tên miền đó đang dùn

Mình đang dùng Google Domains để check tên miền hàng ngày

Từ khi thông báo dịch vụ Google Domains bỏ mác Beta, mình mới để ý và bắt đầ