Các trường hợp nên dùng useCallback và useMemo?

85 lượt xem

profile picture

Ẩn danh

Ngày 13 Tháng 07

Mình thì ko thường dùng hai hook này lắm, nhưng đồng nghiệp thì khuyên nên dùng. Không biết thực tế thì có những trường hợp nào mình nên dùng hai hook này nhỉ?

Đánh giá câu hỏi ngay!

Hãy ấn Up Vote với những câu hỏi cụ thể và chi tiết

Hãy ấn Down Vote với những câu hỏi chưa rõ ràng Careerly sẽ nhắc người hỏi chỉnh sửa lại.

3 câu trả lời

BEST

Ảnh đại diện của Vu Duc Dung

Để có thể đánh giá trường hợp nào nên dùng, ngoài biết cách sử dụng thì cần hiểu cách thức và nguyên lý hoạt động. Theo định nghĩa, useCallback cho phép chúng ta cache lại khai báo hàm giữa mỗi lần re-renders. Vì vậy giá trị trả về của useCallback không thay đổi giữa các lần render trừ khi các dependencies thay thổi. Không khai báo lại: thay vì khai báo lại giữa các lần render, thì nó sẽ trả lại một ref của hàm đã khai báo ở lần đầu. Quá trình khai báo hàm có chiếm dụng tài nguyên mày tính, nhiều hay ít phụ thuộc vào số lượng câu lệnh và kích thước bộ nhớ mà các biến bên trong sử dụng. Không render lại component con: mỗi khi một component render các con của nó cũng sẽ re-render. Điều này là dư thừa nếu component con không phụ thuộc vào các trạng thái có thay đổi của cha. Để khắc phục thì react đã sử dụng memo. Lúc này component con chỉ được render lại, khi nó có phụ thuộc trạng thái từ cha và trạng thái đó thay đổi. Như đã nói ở trên, sử dụng useCallback thì giá trị sẽ không thay đổi giữa các lần render, do đó khi truyền giá trị đó cho component con thì nó sẽ không phải render lại. useMemo có cơ chế và sự ảnh hưởng tương tụ. Nhưng thay vì chỉ cache khai báo hàm thì useMeno cache lại giá trị trả về của hàm. useCallback và useMemo có sự tương đồng nên nhiều người sẽ khó lựa chọn. Sử dụng cái nào phụ thuộc vào cái mà chúng ta quan tâm ở hàm đó. Nếu cái chúng ta cần là giá trị trả về của hàm và cái giá trị đó không thay đổi sau mỗi lần gọi hàm, thì hãy dùng useMeno, gọi lại hàm là lãng phí nếu giá trị trả về của nó đều giống nhau Hiệu năng cải thiện phục thuộc vào nhiều yếu tố, nó sẽ không đáng kể nếu hàm đó chỉ có một vài câu lệnh, hay component con đó chỉ hiển thị môt cái tiêu đề, nhưng nếu component con là một danh sách dài như feed trên facebook thì sao. Các developer thường code trên máy có cầu hình khá ổn, nên đôi khi sự thay đổi không đủ để nhận thấy, Những người dùng bình thường thì lại khác, cần lưu ý chỗ này Link demo: https://codesandbox.io/s/peaceful-tdd-k8z9fl?file=/App.js

Ảnh đại diện của Tín Nguyễn

Không phải là nên dùng hay không, mà là dùng cho trường hợp nào, và không dùng cho trường hợp nào. Nếu dùng để quản trị giá trị của object/hàm để tránh trường hợp mình dùng các giá trị đó trong dependencies cho các useEffect nhằm tránh chạy lại, từ đó ảnh hưởng tới flow/tính đúng đắn thì ok. Còn dùng để tối ưu performance thì không nên. Vì đa số mọi người hay bị overthinking. Tối ưu không đúng cách thì lại khiến mọi thứ phức tạp và tồi tệ hơn rất nhiều. Đã vậy còn tốn thời gian, công sức, maintain này nọ. Hãy chỉ sử dụng khi thật sự có vấn đề về performance. Lúc bạn cảm thấy ứng dụng của mình bị lag, hoặc đo bằng React Profiling và thấy một Component nào đấy render quá nhiều vì giá trị của hàm/object nào đó thay đổi liên tục thì ok. Một trường hợp nên dùng nữa là khi bạn biết biểu thức/hàm đó rất nặng, muốn cache lại giá trị tính toán dựa trên tham số. Ví dụ như: const sum = useMemo(() => a + b, [a, b]) Mình chỉ ví dụ thôi nhé, tưởng tượng a+b này là một hàm f(x), mà khi chạy thì rất tốn chi phí tính toán. Bạn có thể tham khảo thêm bài viết rất hay đến từ Kentc Dodds: https://kentcdodds.com/blog/usememo-and-usecallback

Ảnh đại diện của TrungQuanDev

- Trường hợp này mình cũng có từng chia sẻ ở một Q&A khác gần giống câu hỏi của bạn (link mình sẽ để bên dưới để bạn tham khảo thêm nhé) - Không chắc đồng nghiệp của bạn khuyên dùng nhưng dùng trong trường hợp nào? Trường hợp đó có cần thiết phải dùng đến chúng nó không? - Vì cơ chế của React là các components của nó sẽ được re-render lại mỗi khi props hoặc state thay đổi, đó là cách mà React làm việc, và dĩ nhiên React nó đủ nhanh + tối ưu để làm việc đó." Vì vậy trong hầu hết mọi trường hợp, việc mà trong đầu chúng ta lúc nào cũng nghĩ tới memo các thứ không những là dư thừa (tự làm khó mình) mà còn có khi tác dụng ngược về hiệu suất bởi vì cứ phải cố nghĩ rồi (tốn thời gian phát triển sản phẩm), hoặc đôi khi còn sinh ra bug về logic hiển thị phía UI. - Vậy nên trong phần lớn các trường hợp code thông thường cũng như bắt đầu dự án, thì chưa cần thiết phải nghĩ nhiều tới vấn đề useCallback hay useMemo đâu. - Mà chúng ta sẽ nên áp dụng chúng khi bắt đầu nhận thấy có một page nào đó hay component nào đó cần phải tối ưu. Hay nói theo cách khác là "Chỉ cần thiết áp dụng khi có những chỗ cần phải tối ưu nếu chúng ta thấy nó chậm." - Ví dụ từ bản thân chính mình (đã từng chia sẻ một lần ở link dưới) đó là ngày trước join vào một dự án đang chạy tốt, bỗng nhiên một ngày khách hàng báo về là giỏ hàng bị lag, lúc này mình kiểm tra thì nguyên nhân do giỏ hàng đó của riêng ông khách đó có tới mấy nghìn sản phẩm, và việc còn lại khá đơn giản, lúc này mình mới dùng tới các kỹ thuật memoization để hạn chế re-render không cần thiết và chỉ tối ưu một mình trang đó thôi. - Đây là link tới Q&A trước đó về vấn đề liên quan này, trong đó mình cũng có chia sẻ khá nhiều liên kết tài liệu hữu ích, bạn có thể tham khảo thêm nhé: - https://careerly.vn/qnas/310?utm_campaign=user-share

Đăng ký ngay bây giờ để đọc toàn bộ câu trả lời!

Cộng đồng lập trình viên sẽ giải đáp tường tận cho bạn.

Xem thêm

Đồng ý với Điều khoản dịch vụ Chính sách bảo mật của Careerly

Bạn đã có tài khoản rồi?

Đăng ký ngay bây giờ để đọc toàn bộ câu trả lời!

Cộng đồng lập trình viên sẽ giải đáp tường tận cho bạn.