- vừa được xem lúc

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

0 0 52

Người đăng: Nghiệp

Theo Viblo Asia

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 cách này 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, registerables } from "chart.js"; export default function App() { const ref = useRef<HTMLCanvasElement | null>(null); useEffect(() => { const myChart = new Chart(ref.current!, { type: "line", data: chartData }); return () => { myChart.destroy(); }; }, []); return ( <div className="App"> <h1>Implement Chart.js with useRef()</h1> <canvas ref={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 nó 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:

export default function App() { const ref = useCallback(async (node) => { const { Chart, registerables } = await import("chart.js"); if (node instanceof HTMLCanvasElement) { new Chart(node, { type: "line", data: chartData }); } }, []); return ( <div className="App"> <h1>Implement Chart.js with useCallback()</h1> <canvas ref={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"; export default function App() { const { ref: inViewRef, inView: showChart } = useInView({ triggerOnce: true }); const ref = useCallback(async (node) => { const { Chart, registerables } = await import("chart.js"); Chart.register(...registerables); if (node instanceof HTMLCanvasElement) { new Chart(node, { type: "line", data: chartData }); } }, []); return ( <div className="App"> <h1>Implement Chart.js with useCallback()</h1> <div> Lorem, ipsum dolor sit amet consectetur.... </div> <section ref={inViewRef} style={{ height: 400 }}> {showChart && <canvas ref={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 && <canvas ref={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" ?

Bình luận

Bài viết tương tự

- vừa được xem lúc

React Hooks + Context API = Redux?

Khi làm việc với Redux, nó yêu cầu một lượng code lớn. Và điều này có thể khiến mã nguồn của chúng ta trở nên rất phức tạp và khó bảo trì.

0 0 305

- vừa được xem lúc

Sử dụng Context trong React theo cách đơn giản nhất

Sử dụng Context trong React theo cách đơn giản nhất. Bạn đã bao giờ gặp trường hợp một Prop được yêu cầu bởi một component ở mọi nơi trong hierarchy tree.

0 0 54

- vừa được xem lúc

Một số lưu ý khi sử dụng React Hook

. Cách tốt nhất để bắt đầu với React hook là học cách sử dụng chúng như thế nào. Trong bài này, chúng ta cùng tìm hiểu một số lưu ý thông qua các ví dụ về sai lầm khi sử dụng React hook, và cách khắc phục chúng nhé.

0 0 100

- vừa được xem lúc

React Hook router

Giới thiệu chung. React Router là một thư viện nhẹ cho phép bạn quản lý và xử lý việc định tuyến cho ứng dụng React của mình.

0 0 223

- vừa được xem lúc

Thao tác với các phần tử DOM với React Hook sử dụng useRef()

Xử lý DOM là kỹ thuật căn bản mà mọi lập trình frontend cần nắm, tuy nhiên nhiều anh em không cảm thấy hứng thú khi sử dụng refs. .

0 0 50

- vừa được xem lúc

Tìm hiểu về React Hook: Sử dụng useDebugValue

Trong bài viết hôm này, tôi sẽ giới thiệu các bạn một React Hook tiếp theo, đó là useDebugValue. useDebugValue là gì .

0 0 58