Giới Thiệu
Trong bài viết này, chúng ta sẽ tìm hiểu cách tạo một hook tùy chỉnh trong React có tên là usePrevious(). Hook này cho phép bạn lấy giá trị trước đó của một biến trạng thái, giúp dễ dàng theo dõi sự thay đổi của trạng thái qua từng lần render. Điều này rất hữu ích trong nhiều tình huống khi bạn cần so sánh giá trị hiện tại với giá trị trước đó.
Nội Dung
Mục Tiêu
Mục tiêu của chúng ta là xây dựng hook usePrevious() với giá trị trước đó khởi tạo là undefined. Dưới đây là mã khởi tạo:
typescript
export function usePrevious<T>(value: T): T | undefined {
// your code here
}
// Nếu bạn muốn thử nghiệm mã của mình, hãy nhớ xuất khẩu thành phần App() như bên dưới
// export function App() {
// return <div>your app</div>
// }
Cách Thực Hiện
Sử Dụng useRef
Chúng ta sẽ sử dụng useRef để lưu trữ giá trị của trạng thái, nhằm tránh việc re-render không cần thiết.
typescript
const ref = useRef<T>()
Cập Nhật Giá Trị Trước Đó
Để lưu trữ giá trị trước đó sau mỗi lần render, chúng ta sẽ sử dụng thuộc tính .current của ref:
typescript
useEffect(() => {
ref.current = value;
}, [value])
return ref.current;
Giải Thích Cách Hoạt Động
Hook useEffect sẽ chạy sau mỗi lần render, giúp giữ lại giá trị trước đó và ngăn không cho nó được cập nhật. Để minh họa, chúng ta sẽ tạo một trạng thái đếm để hiển thị giá trị hiện tại và một trạng thái prevCount để hiển thị giá trị trước đó mà chúng ta đã lưu. Dưới đây là mã hoàn chỉnh:
typescript
import React, { useEffect, useRef, useState } from 'react';
export function usePrevious<T>(value: T): T | undefined {
const ref = useRef<T>()
useEffect(() => {
ref.current = value;
}, [value])
return ref.current;
}
export function App() {
const [count, setCount] = useState(0);
const prevCount = usePrevious(count);
return (
<div>
<p>Hiện tại: {count}, trước đó: {prevCount}</p>
<button onClick={() => setCount(c => c + 1)}>Tăng</button>
</div>
);
}
Thực Hành
Hướng Dẫn Bước Từng Bước
- Tạo hook
usePrevious: Sử dụnguseRefđể lưu giá trị. - Cập nhật giá trị trong
useEffect: Lưu giá trị mới vàoref.currentmỗi khi giá trị thay đổi. - Sử dụng hook trong thành phần
App: Hiển thị cả giá trị hiện tại và giá trị trước đó.
Ví Dụ Thực Tế
Giả sử bạn đang phát triển một ứng dụng đếm số lượt nhấp chuột. Khi người dùng nhấp vào nút, bạn muốn hiển thị số lần nhấp hiện tại và số lần nhấp trước đó. Hook usePrevious() sẽ giúp bạn làm điều này dễ dàng.
Mẹo Tối Ưu Hiệu Năng
- Tránh Re-render Không Cần Thiết: Sử dụng
useRefđể tránh việc re-render khi giá trị không thay đổi. - Giới Hạn Số Lần Gọi
useEffect: Chỉ đặt các thuộc tính phụ thuộc cần thiết trong mảng phụ thuộc để tối ưu hóa hiệu suất.
Cách Khắc Phục Lỗi
- Giá Trị Trả Về Là
undefined: Đảm bảo rằng bạn đã khởi tạo giá trị và không quên cập nhậtref.currenttronguseEffect. - Vấn Đề Với Render: Kiểm tra lại mảng phụ thuộc trong
useEffectđể đảm bảo nó được cập nhật đúng cách.
Kết Luận
Hook usePrevious() là công cụ mạnh mẽ giúp bạn theo dõi các giá trị trước đó trong React. Hãy thử nghiệm với mã mẫu và áp dụng nó vào dự án của bạn. Nếu bạn có bất kỳ câu hỏi nào, đừng ngần ngại để lại bình luận bên dưới! Hãy chia sẻ bài viết này với cộng đồng lập trình viên để mọi người cùng học hỏi.
Câu Hỏi Thường Gặp
1. usePrevious() có thể sử dụng cho các loại giá trị nào?
- Hook này có thể sử dụng cho bất kỳ loại giá trị nào, bao gồm số, chuỗi, đối tượng, v.v.
2. Liệu có cách nào khác để lưu giá trị trước đó không?
- Có, bạn có thể sử dụng Redux hoặc Context API để quản lý trạng thái, nhưng
usePrevious()là giải pháp đơn giản và hiệu quả cho những trường hợp nhỏ.
3. Tại sao không sử dụng state để lưu giá trị trước đó?
useStatesẽ gây ra re-render mỗi khi giá trị thay đổi, trong khiuseRefkhông làm như vậy, giúp tối ưu hóa hiệu suất.
4. Hook này có tương thích với các phiên bản React cũ hơn không?
- Không,
useRefvàuseEffectchỉ có sẵn từ React 16.8 trở đi. Hãy đảm bảo rằng bạn đang sử dụng phiên bản mới nhất.
Liên Kết Tài Nguyên
Lời Kêu Gọi Hành Động
Hãy thử áp dụng usePrevious() trong dự án của bạn ngay hôm nay và chia sẻ kinh nghiệm của bạn với cộng đồng lập trình viên!