React.memo là gì
React.memo là một Higher Order Component (HOC) bao bọc xung quanh một Component để ghi nhớ kết quả render và bỏ qua các re-render không cần thiết.
HOC khi được sử dụng sẽ tạo ra một [memoized version]
hoặc [optimal version]
của Component để tăng tốc quá trình render.
- Higher Order Component (HOC): về bản chất, nó là một hàm nhận vào Component và sau đó trả về một Component mới.
[memoized version]
hoặc[optimal version]
: kết quả hiển thị của Component sẽ được ghi nhớ, cho nên React sẽ bỏ qua render và sử dụng lại kết quả trước đó.- Chỉ kiểm tra prop change: nếu các props được truyền xuống thay đổi, thì một render mới sẽ xảy ra. Nếu props giữ nguyên, bạn sẽ luôn nhận được kết quả trước đó.
- Ảnh hưởng đến React Hooks: React luôn re-render Component nếu state thay đổi, ngay cả khi Component được bọc trong React.memo().
Sử dụng React Memo ở đâu?
Dưới đây là một số điểm quan trọng cần lưu ý về nơi sử dụng chúng:
- pure functional component:
- render often:
- re-render with same props:
- medium to big size:
Nếu đáp ứng được 4 điều kiện bên trên thì có thể dùng React.memo(). Còn nếu không có đủ thì cần đánh giá thêm có nên xài hay không.
Trường hợp hay gặp nhất là: <Todos todos={todos} />
, khi đó todos nhận được sẽ luôn là 1 Object mới mặc dù data bên trong không có thay đổi.
1 trường hợp khác là re-render Component Cha làm Component Con re-render theo
trong ví dụ này việc thay đổi [views] sẽ không ảnh hưởng gì đến kết quả hiển thị của Movie, nhưng nó vẫn bị re-render vì MovieViewsRealtime re-render
Component Cha: export function MovieViewsRealtime({ title, releaseDate, views })
Component Con: export function Movie({ title, releaseDate })
cách fix:
Component Con: export const MemoizedMovie = React.memo(Movie);
Component Cha lúc này sẽ dùng MemoizedMovie thay cho Movie
Đây chỉ là ví dụ về các trường hợp có thể sử dụng, thực tế cần đánh giá 4 tiêu chí bên trên, ví như không render thường xuyên hoặc không re-render thì không nên xài, Component Con không tốn nhiều tài nguyên và thời gian thì cũng không cần xài.
vẫn câu nói trên: Tối ưu hóa hiệu suất không miễn phí. Chúng LUÔN đi kèm với chi phí nhưng KHÔNG phải lúc nào cũng đi kèm với lợi ích để bù đắp chi phí đó.
Cấu trúc
React.memo(Component, [areEqual(prevProps, nextProps)]);
trong đó:
- Component: yêu cầu đáp ứng 4 điều kiện phía trên
- areEqual (Optional): là function nếu bạn muốn kiểm soát việc Compare, không thì React.memo sẽ chỉ làm shallowly compare
areEqual(prevProps, nextProps) phải trả về true nếu prevProps và nextProps bằng nhau, lúc này Component sẽ không render lại.
Khi nào nên tránh React.memo()
Bất cứ khi nào không nên dùng React.memo() chính là nên tránh
Sử dụng React.memo() cũng tốn thêm tài nguyên, nên hãy sử dụng một cách thông minh, đừng quên dùng các công cụ đo lường để đo hiệu suất trước và sau khi sử dụng.
Kết luận
- React.memo được sử sử dụng để tránh re-render lại Component mà nó bao bọc
- Có 2 trường hợp React.memo chắc chắn sẽ re-render lại, là props thay đổi và state bên trong thay đổi
- Việc sử dụng React.memo có tốn thêm tài nguyên, nên hãy sử dụng thông minh, nếu không đáp ứng được 4 điều kiện bên trên thì nên tránh dùng nó