-->
ads here

What is React.memo and How to use it?

advertise here
Hello, bài viết hôm nay mình sẽ giới thiệu đến mọi người một khái niệm của React được giới thiệu trong phiên bản 16.6 đó chính là React.memo.
enter image description here

1. Giới thiệu về React.memo

Trong React, với 1 class component ta có thể bỏ qua việc render lại component khi props được truyền vào giống nhau bằng cách chuyển nó thành PureComponent hoặc dùng hàm shouldComponentUpdate(). Vậy nếu component của bạn ở dạng function component thì như thế nào?
Khi đó chúng ta cần tới React.memo. Đây là một High Order Component tương tự như PureComponent nhưng dùng cho function component.

const MyMemo = React.memo(function MyComponent(){ // only render when props change })

2. Cách thức hoạt động

Khi quyết định cập nhật DOM, React đầu tiên sẽ render component, tiếp đó, với mỗi lần render, React sẽ so sánh kết quả render giữa các lần với nhau, nếu các kết quả đó khác nhau thì DOM mới được cập nhật.

React.memo

Nếu component render cùng 1 kết quả khi truyền cùng 1 props, thì ta có thể wrap nó trong React.memo để làm tăng hiệu suất bằng cách ghi nhớ kết quả render. Cụ thể như sau: Khi function component được wrap trong React.memo thì kết quả render sẽ được nhớ (memoize). Trước lần render tiếp theo, vì props không đổi nên kết quả không thay đổi, nên thay vì render lần nữa thì thì React sẽ dùng lại kết quả đã được nhớ lúc đầu.
Chúng ta có thể tham khảo ví dụ sau:
export function Movie({title, date}) { return ( <div> <h1>{title}</h1> <span>{date}</span> </div> ) } export const MemoizedMovie = React.memo(Movie)
React.memo(Movie) trả về một memoized component tên là MemoizedMovie. Component này giống hệt Movie ngoại trừ 1 điều là: Kết quả render của MemoizedMovie được nhớ. Kết quả nhớ này sẽ được dùng lại miễn là props title và date được giữ nguyên ở lần render tiếp theo. Điều này sẽ cải thiện được hiệu suất vì khi tái sử dụng nội dung được nhớ (memoized content), React sẽ bỏ qua được việc re-render component và đồng thời không thực hiện việc difference check đối với DOM
// First render. React calls MemoizedMovie function. <MemoizedMovie title="Heat" releaseDate="December 15, 1995" /> // On next round, React used memoized content instead of calling MemoizedMovie,prevent re-rendering <MemoizedMovie title="Heat" releaseDate="December 15, 1995" /> // Same props

Customize props check

Mặc định, React.memo chỉ shallow compare props và object của props. Chúng ta có thể dùng 1 tham số thứ 2 để tùy biến hàm equality check:
React.memo(Component, areEqual(prevProps, nextProps))
Ví dụ, ta tạo thêm 1 memoized Component là MemoizedMovie2 như sau:
const areEqual = (prevProps, nextProps) => prevProps.title === nextProps.title && prevProps.date === nextProps.date; const MemoizedMovie2 = React.memo(Movie, areEqual)

3. Khi nào nên sử dụng React.memo

Một trong những trường hợp tốt nhất để dùng React.memo đó là khi chúng ta mong muốn function component render thường xuyên với cùng props. Một ví dụ điển hình là function component bị bắt buộc render bởi component cha.
Hãy xét ví dụ dưới đây:
Ta sẽ dùng lại component Movie đã tạo ở trên, và tạo thêm 1 component MovieViewsRealtime để cập nhật realtime số lượt view của từng bộ phim

function MovieViewsRealtime({title, date, views}) { return ( <div> <Movie title={title} date={date} /> <span>Views: {views} </span> </div> ) }
Khi chạy, ứng dụng sẽ poll lên server mối giây để lấy thông tin về lượt views của phim
// Initial render (0s), views = 0 <MovieViewsRealtime title="No time to die" date="01/04/2020" views={0} /> // After 1s, views = 10 <MovieViewsRealtime title="No time to die" date="01/04/2020" views={10} /> // After 2s, views = 20 <MovieViewsRealtime title="No time to die" date="01/04/2020" views={20} /> // and so on
Mỗi lần props views thay đổi thì MovieViewsRealtime sẽ được re-render, kéo theo Movie sẽ re-render mặc dù title và date không thay đổi. Lúc này, ta cần áp dụng React.memo cho Movie component.
Chúng ta sửa MovieViewsRealtime để sử dụng MemoizedMovie
function MovieViewsRealtime({title, date, views}) { return ( <div> <MemoizedMovie title={title} date={date} /> <span>Views: {views} </span> </div> ) }
Lúc này, chỉ cần title và date không thay đổi, React sẽ bỏ qua việc render MemoizeMovie, nhờ đó cải thiện được performance cho MovieViewsRealtime.

Kết

React.memo là công cụ tuyệt vời để memoized cho function component. Nếu áp dụng chính xác, performance có thể được cải thiện vì sẽ tránh được việc re-render nếu nextProps và prevProps không thay đổi. Chúng ta có thể sử dụng profiling để đo lường performance của việc dùng React.memo.
Bạn có biết những use case nào khác sử dụng React.memo không? Nếu có hãy comment ở dưới đây nhé. Thanks!

Reference

Advertisement
COMMENTS ()