0
0
Lập trình
NM

Hướng Dẫn Tạo Hook usePrevious() Trong React

Đăng vào 1 tháng trước

• 4 phút đọc

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 Copy
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 Copy
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 Copy
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 Copy
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

  1. Tạo hook usePrevious: Sử dụng useRef để lưu giá trị.
  2. Cập nhật giá trị trong useEffect: Lưu giá trị mới vào ref.current mỗi khi giá trị thay đổi.
  3. 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ật ref.current trong useEffect.
  • 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 đó?

  • useState sẽ gây ra re-render mỗi khi giá trị thay đổi, trong khi useRef khô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, useRefuseEffect chỉ 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!

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào