ReactJS - Custom Hooks: Mastering Infinite Scroll

Xin chào các bạn lập trình viên React tiềm năng! Hôm nay, chúng ta sẽ bắt đầu một hành trình thú vị vào thế giới của các custom hooks, cụ thể là việc thực hiện chức năng cuộn vô hạn. Là giáo viên khoa học máy tính gần gũi của bạn, tôi sẽ hướng dẫn bạn qua quy trình này từng bước, đảm bảo bạn nắm vững mọi khái niệm trên đường đi. Vậy, hãy lấy đồ uống yêu thích của bạn, ngồi thoải mái, và cùng nhau khám phá nhé!

ReactJS - Custom Hooks

Understanding Custom Hooks

Trước khi chúng ta深入研究 vào cuộn vô hạn, hãy dành một chút thời gian để hiểu về custom hooks là gì. Trong React, hooks là các hàm cho phép bạn "hook vào" các tính năng của state và lifecycle từ các component hàm. Custom hooks chỉ đơn giản là các hàm sử dụng các hooks khác và có thể chia sẻ giữa các component.

Hãy tưởng tượng custom hooks như là cây kéo đa năng cá nhân của bạn trong phát triển React. Chúng giúp bạn tách logic của component ra thành các hàm có thể tái sử dụng, làm cho mã của bạn sạch sẽ và modul hơn.

Implementing Infinite Scroll Functionality

Bây giờ, hãy cùng giải quyết ngôi sao của chúng ta: chức năng cuộn vô hạn. Bạn có thể đã gặp tính năng này trên các nền tảng mạng xã hội hoặc các trang web tin tức, nơi nội dung liên tục được tải khi bạn cuộn xuống. Đây là một cách tuyệt vời để nâng cao trải nghiệm người dùng bằng cách trình bày nội dung mà không cần phân trang.

The Basics of Infinite Scroll

Tạiõi cốt lõi, cuộn vô hạn liên quan đến ba bước chính:

  1. Phát hiện khi người dùng cuộn đến cuối trang
  2. Khởi động một yêu cầu để tải thêm dữ liệu
  3. Thêm dữ liệu mới vào nội dung hiện có

Hãy phá vỡ điều này thành các phần nhỏ hơn và tạo custom hook của chúng ta.

Implementing useInfiniteScroll Hook

Chúng ta sẽ tạo một custom hook叫做 useInfiniteScroll. Hook này sẽ xử lý logic để phát hiện khi nào tải thêm nội dung và cung cấp cho chúng ta state và các hàm cần thiết để thực hiện cuộn vô hạn trong các component.

Dưới đây là cấu trúc cơ bản của hook:

import { useState, useEffect } from 'react';

const useInfiniteScroll = (callback) => {
const [isFetching, setIsFetching] = useState(false);

useEffect(() => {
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);

useEffect(() => {
if (!isFetching) return;
callback();
}, [isFetching]);

function handleScroll() {
if (window.innerHeight + document.documentElement.scrollTop !== document.documentElement.offsetHeight || isFetching) return;
setIsFetching(true);
}

return [isFetching, setIsFetching];
};

export default useInfiniteScroll;

Hãy phân tích từng phần:

  1. Chúng ta nhập useStateuseEffect từ React. Đây là các khối xây dựng của hook của chúng ta.

  2. Hook useInfiniteScroll nhận một hàm callback làm đối số. Đây sẽ là hàm tải thêm dữ liệu khi được kích hoạt.

  3. Chúng ta tạo một biến state isFetching bằng useState. Điều này sẽ theo dõi xem chúng ta có đang fetching dữ liệu hay không.

  4. useEffect đầu tiên thêm một event listener cho sự kiện cuộn khi component được mount và loại bỏ nó khi component được unmount. Đây là cách chúng ta dọn dẹp để tránh rò rỉ bộ nhớ.

  5. useEffect thứ hai theo dõi các thay đổi trong isFetching. Khi nó trở thành true, nó gọi hàm callback của chúng ta để fetch thêm dữ liệu.

  6. Hàm handleScroll là nơi xảy ra phép màu. Nó kiểm tra xem chúng ta đã cuộn đến cuối trang hay chưa và chúng ta có đang fetching dữ liệu hay không. Nếu cả hai điều kiện đều thỏa mãn, nó đặt isFetching thành true.

  7. Cuối cùng, chúng ta trả về isFetchingsetIsFetching để component sử dụng hook này có thể truy cập và cập nhật state này.

Bây giờ, hãy xem cách chúng ta có thể sử dụng hook này trong một component:

import React, { useState } from 'react';
import useInfiniteScroll from './useInfiniteScroll';

const InfiniteScrollComponent = () => {
const [items, setItems] = useState([]);
const [isFetching, setIsFetching] = useInfiniteScroll(fetchMoreListItems);

function fetchMoreListItems() {
// Simulating an API call
setTimeout(() => {
setItems(prevItems => ([...prevItems, ...Array(20).fill(0).map((_, i) => ({ id: prevItems.length + i, name: `Item ${prevItems.length + i + 1}` }))]));
setIsFetching(false);
}, 2000);
}

return (
<div>
<ul>
{items.map(item => <li key={item.id}>{item.name}</li>)}
</ul>
{isFetching && 'Fetching more list items...'}
</div>
);
};

export default InfiniteScrollComponent;

Trong component này:

  1. Chúng ta sử dụng hook useInfiniteScroll, truyền cho nó hàm fetchMoreListItems.
  2. fetchMoreListItems mô phỏng một yêu cầu API, thêm 20 mục mới vào danh sách sau một迟延 2 giây.
  3. Chúng ta render các mục danh sách và hiển thị thông báo đang tải khi isFetching là true.

Và thế là xong! Một việc thực hiện cuộn vô hạn hoàn chỉnh bằng cách sử dụng một custom hook React.

Nhớ rằng, vẻ đẹp của custom hooks là tính tái sử dụng của chúng. Bây giờ bạn có thể sử dụng hook useInfiniteScroll này trong bất kỳ component nào cần chức năng cuộn vô hạn.

Conclusion

Custom hooks là một tính năng mạnh mẽ trong React cho phép chúng ta tạo logic tái sử dụng. Bằng cách thực hiện cuộn vô hạn dưới dạng một custom hook, chúng ta đã tạo ra một giải pháp linh hoạt, có thể tái sử dụng và dễ dàng tích hợp vào các component khác nhau.

Trong hành trình tiếp tục của bạn với React, hãy tiếp tục khám phá và tạo các custom hooks. Chúng là một cách tuyệt vời để giữ cho mã của bạn DRY (Don't Repeat Yourself) và duy trì một mã sạch sẽ, modul.

Chúc các bạn lập trình vui vẻ, và may cuộn của bạn sẽ vô hạn! ??

Credits: Image by storyset