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

React Memo và useMemo

0 0 30

Người đăng: Nguyen Phuc Cuong

Theo Viblo Asia

Từ phiên bản react 16.6 facebook giới thiệu lazy, memo, contexType. Công dụng thì các cụ có thể tham khảo link này

React Memo

React memo sinh ra với mục địch tránh việc rerender nhiều lần ảnh hưởng đến performance. Cũng giống như việc dùng PureComponent hay shouldComponentUpdate được viết một cách ngắn gọn như sau

const MyComponent = React.memo(function MyComponent(props) { /* only rerenders if props change */
});

Chúng ta hãy xem 1 ví dụ đơn giản với react meno sau đây

const Child = React.memo(props => { console.log("rendered"); return <React.Fragment>{props.name}</React.Fragment>;
}); class App extends React.Component { state = { value: 1, name: "Jioke" }; handleClick = () => { this.setState({ value: this.state.value + 1 }); }; render() { return ( <React.Fragment> <Child name={this.state.name} /> <div>{this.state.value}</div> <button onClick={this.handleClick}>+</button> </React.Fragment> ); }
}

Component Child của chúng ta đang bao là một react Memo, như vậy chúng có tác dụng gì chúng ta cùng phân tích nhé

Thứ nhất nó nhận prop là name truyền từ component App, bình thường mỗi lần chúng ta click button giá trị value thay đổi + 1. Và tất cả được rerender lại update lại Dom để chúng ta có thể nhìn thấy sự thay đổi.

Thứ 2 là có memo thi sao, khi chúng ta nhấn click button chỉ có giá trị value thay đổi name không đổi và được truyền vào component Child vì là có memo nên nó sẽ check prop chuyền vào có thay đổi không nếu thay đổi chúng sẽ rerender còn không thay đổi sẽ không cần làm gì, tương đối giống với việc sự dụng shouldComponentUpdate trong class component hay PureComponent phải không nào. Nhưng code nó sáng sủa mà dễ hiểu hơn rất nhiều phải không?

Cùng xem ví dụ trên codeopen nhé.

Mỗi lần chúng ta click button thì component Child không hề được render lại, chúng ta chỉ thấy trong console chỉ duy nhất 1 lần rendered được in ra phải không. Và bạn có thể xóa memo đi xem kết quả sẽ thế nào nhé. Khi đó bạn sẽ thấy hiệu năng của nó, rất tuyệt vời phải không nào.

Từ phiên bản 16.8 facebook lại giới thiệu cho chúng ta khái niệm hook, ai chưa biết có thể tham khảo tại đây

Vậy hook sinh ra cho mục đích gì nó gồm những thành phần nào? các cụ tự tìm hiểu. Mình xin nói qua là khi dùng function component thì chúng chỉ đơn giản return ra 1 cái gì đó mà không dùng được lifecycle. Hook sinh ra là làm cho function component từ cái đơn giản có thể dùng được state, call api như một class component mà nó thực sự là sự chuyển mình một sự thay thế hoàn hảo cho class component.

useMemo

useMemo cũng giống như khái niệm memo, nó optimize việc render giống như shouldComponentUpdate trong class component chỉ khác là nó nằm trong hook. Chỉ có 1 sự khác biệt là chúng ta phải truyền thêm tham số để so sánh, quyết định khi nào cần render Ví dụ:

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

a,b là 2 tham số truyền vào useMemo để quyết định sự thay đổi như shouldComponentUpdate thôi

Trong react Memo tham số nó là props chuyền vào cho Child component.

Bây giờ chúng ta đi xét ví dụ sau

import React, { useState, useMemo } from "react";
import ReactDOM from "react-dom"; function App() { const [count, setCount] = useState(0); const [wordIndex, setWordIndex] = useState(0); const words = ["hey", "this", "is", "cool"]; const word = words[wordIndex]; const computeLetterCount = word => { let i = 0; while (i < 1000000000) i++; return word.length; }; const letterCount = useMemo(() => computeLetterCount(word), [word]); return ( <div style={{ padding: "15px" }}> <h2>Compute number of letters (slow ?)</h2> <p> "{word}" has {letterCount} letters </p> <button onClick={() => { const next = wordIndex + 1 === words.length ? 0 : wordIndex + 1; setWordIndex(next); }} > Next word </button> <br /> <br /> <h2>Increment a counter (fast ⚡️)</h2> <p>Counter: {count}</p> <button onClick={() => setCount(count + 1)}>Increment</button> </div> );
} const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement); 

Trong component App ta có 2 function thay đổi state là setCountsetWordIndex, function setWordIndex return index of array. Trong function computeLetterCount truyền vào word và trả về chiều dài của word truyền vào, điều đặc biệt là function computeLetterCount sử dụng useMemo để tối ưu cho việc rerender. Chỉ khi nào wordthay đổi thì function computeLetterCount mới được gọi. Như thế nó khá giống với ví dụ cho react memo ở trên phải không nào.

Cùng chạy ví dụ trên bằng codeopen này nhé.

Các bạn xem console sẽ hiểu bản chất của vấn đề, khi ta bấm Increment button thì function computeLetterCount không hề được gọi vì nó đang sử dụng useMemo. Còn khi bấm button nextword thì function computeLetterCount mới được gọi vì word thay đổi.

Qua 2 ví dụ trên ta thấy React MemouseMemo là khá tương đồng bạn có thể dùng React MemouseMemo để tối ưu hóa việc render cho class component, function component.

Trong boilerplate react khi ta sử dụng generate để render function component, nó tự động add thêm React Memo cho chúng ta, các bạn thử điều này nhé, nó cũng thật hữu ích cho chúng ta tiết kiệm khá khá thời gian phải không.

Bình luận

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

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

Giới thiệu Typescript - Sự khác nhau giữa Typescript và Javascript

Typescript là gì. TypeScript là một ngôn ngữ giúp cung cấp quy mô lớn hơn so với JavaScript.

0 0 499

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

Cài đặt WSL / WSL2 trên Windows 10 để code như trên Ubuntu

Sau vài ba năm mình chuyển qua code trên Ubuntu thì thật không thể phủ nhận rằng mình đã yêu em nó. Cá nhân mình sử dụng Ubuntu để code web thì thật là tuyệt vời.

0 0 374

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

Đặt tên commit message sao cho "tình nghĩa anh em chắc chắn bền lâu"????

. Lời mở đầu. .

1 1 701

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

Tìm hiểu về Resource Controller trong Laravel

Giới thiệu. Trong laravel, việc sử dụng các route post, get, group để gọi đến 1 action của Controller đã là quá quen đối với các bạn sử dụng framework này.

0 0 335

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

Phân quyền đơn giản với package Laravel permission

Như các bạn đã biết, phân quyền trong một ứng dụng là một phần không thể thiếu trong việc phát triển phần mềm, dù đó là ứng dụng web hay là mobile. Vậy nên, hôm nay mình sẽ giới thiệu một package có thể giúp các bạn phân quyền nhanh và đơn giản trong một website được viết bằng PHP với framework là L

0 0 420

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

Bạn đã biết các tips này khi làm việc với chuỗi trong JavaScript chưa ?

Hi xin chào các bạn, tiếp tục chuỗi chủ đề về cái thằng JavaScript này, hôm nay mình sẽ giới thiệu cho các bạn một số thủ thuật hay ho khi làm việc với chuỗi trong JavaScript có thể bạn đã hoặc chưa từng dùng. Cụ thể như nào thì hãy cùng mình tìm hiểu trong bài viết này nhé (go).

0 0 414