Hook tối ưu hiệu suất useMemo trong React
Hook tối ưu hiệu suất đầu tiên
mà chúng ta xem xét
- đó là useMemo.
Hook này giúp cache kết quả của các thao tác tốn tài nguyên giữa các lần render lại màn hình và do đó có thể giúp tránh các tính toán nặng không cần thiết. Việc cache như vậy còn được gọi là memoization.
Hãy xem cách nó hoạt động. Hãy
tạo một component với nút bấm và
tiêu đề h3:
return (
<div>
<h3>Văn bản</h3>
<button>nhấp</button>
</div>
);
Bây giờ hãy làm sao để khi nhấp vào
tiêu đề, màu sắc của nó thay đổi từ cam
sang xanh lá và ngược lại. Đầu tiên
hãy tạo state isGreen:
const [isGreen, setIsGreen] = useState(false);
Thêm vào thuộc tính style của tiêu đề
điều kiện thay đổi màu sắc và
gán trình xử lý sự kiện nhấp chuột:
<h3 onClick={() => setIsGreen(!isGreen)}
style={{ color: isGreen ? 'green' : 'orangered' }}
>Văn bản</h3>
Giả sử chúng ta cũng có một giá trị nào đó, sẽ tăng lên một đơn vị khi nhấp vào nút của chúng ta. Hãy tạo state cho nó:
const [num, setNum] = useState(0);
Thêm xử lý sự kiện nhấp chuột vào nút:
<button onClick={() => setNum(num + 1)}>
số lần nhấp
</button>
Giả sử chúng ta cũng có một hàm nào đó
square, sẽ trả về
bình phương của giá trị num. Kết quả
gọi hàm chúng ta sẽ ghi vào
biến result:
const result = square(num);
function square(num) {
return num * num;
}
Hãy hiển thị result trong văn bản của nút:
<button onClick={() => setNum(num + 1)}>
số lần nhấp: {result}
</button>
Kết quả chúng ta có được như sau:
khi nhấp vào nút, giá trị
num thay đổi, sau đó được lũy thừa
bình phương, còn khi nhấp vào tiêu đề
màu sắc của tiêu đề thay đổi.
Component của chúng ta rất nhỏ, mọi thứ hoạt động nhanh chóng, mặc dù khi nhấp vào tiêu đề để thay đổi màu sắc của nó, toàn bộ component được render lại từ đầu, do đó các tính toán gắn liền với nút cũng diễn ra lại từ đầu, ngay cả khi chúng ta không chạm vào nó. Và bây giờ hãy tưởng tượng nếu các tính toán của chúng ta là nặng nề và tất cả lại được tính toán lại mỗi lần.
Hãy làm cho hàm của chúng ta nặng hơn một chút, bây giờ nó sẽ "suy nghĩ" lâu hơn một chút. Bằng cách này chúng ta sẽ mô phỏng các tính toán lâu:
function square(num) {
let startTime = performance.now();
while (performance.now() - startTime < 500) {
// Chỉ không làm gì cả ...
}
return num * num;
}
Bây giờ hãy thử nhấp vào tiêu đề. Hóa ra
bây giờ do hàm square làm việc lâu
(mà chúng ta không chạm vào nút)
chúng ta phải đợi một khoảng thời gian dài để
màu sắc của tiêu đề thay đổi!
Ở đây, hook useMemo sẽ đến cứu chúng ta.
Để làm điều này, chúng ta cần truyền vào tham số đầu tiên
một hàm tính toán
giá trị mà chúng ta muốn cache,
hàm này phải là pure và không
nhận bất kỳ tham số nào. Còn tham số thứ hai
- là các dependencies trong dấu ngoặc vuông,
nói cách khác, tất cả các giá trị reactive
tham gia vào mã của
hàm. Do đó, trong result
bây giờ chúng ta sẽ viết một cấu trúc như thế này:
const result = useMemo(() => square(num), [num]);
Hãy nhấp vào tiêu đề một lần nữa. Bây giờ,
nếu chúng ta không chạm vào nút có các tính toán
và không thay đổi giá trị state
num theo cách đó, thì không có gì được tính lại,
và React hiển thị giá trị đã cache
trong nút, do đó tiêu đề của chúng ta
nhanh chóng thay đổi màu sắc của nó.
Tạo component App, đặt
trong đó một đoạn văn. Tạo state text
với giá trị ban đầu 'react',
giá trị của state được hiển thị
như là văn bản của đoạn văn. Khi nhấp chuột
vào đoạn văn, hãy thêm vào cuối văn bản của nó
một dấu chấm than.
Tạo thêm một state num, với
giá trị ban đầu 0. Đặt trong
App một đoạn văn khác. Làm sao để
khi nhấp chuột vào nó, num
tăng lên 1.
Và bây giờ hãy thêm vào App hàm
triple, nhận
num làm tham số và
trả về giá trị gấp ba lần của nó.
Đặt kết quả gọi hàm
vào biến result. Hiển thị
result như là văn bản của đoạn văn thứ hai.
Nhấp lần lượt vào các đoạn văn,
nhận thấy dấu chấm than được thêm vào
chậm như thế nào.
Hãy sửa tình huống này, bằng cách bọc hàm chậm
triple vào useMemo.