Avatar

Huy Pham

23/03/2022|2 phút đọc
0
0

Xây dựng một Infinite Scroll Component với React Hooks

khi sử dụng các trang web, đặc biệt là mạng xã hội, có lẽ các bạn đã không ít lần nhìn thấy họ sử dụng kỹ thuật Infinite Scroll (cuộn vô hạn). Đây là kỹ thuật dùng đễ lấy một lượng dữ liệu cần thiết để hiển thị lên trang web và chỉ lấy thêm dữ liệu khi người dùng cuộn đến cuối trang. Trong bài viết này, mình và các bạn sẽ cùng tìm hiểu cách để tạo ra một Infinite Scroll Component sử dụng React Hooks.

infinite-scroll-react-hooks.jpg

Bắt đầu thôi:

Trong bài viết này mình sẽ sử dụng api từ JSONPlaceholder và mình chỉ tập trung vào xây dựng Infinite Scroll Component mà không quá chú trọng về UI.

Đầu tiên mình sẽ tạo vài state đơn giản phục vụ cho việc pagination và dùng useEffect để fetch dữ liệu ban đầu.

function App() {
  const [page, setPage] = useState(1);
  const [totalRows, setTotalRows] = useState(0);
  const [posts, setPosts] = useState([]);

  useEffect(() => {
    (async () => {
      const response = await (
        await fetch(
          `http://js-post-api.herokuapp.com/api/posts?_page=${page}&_limit=10`
        )
      ).json();
      setPosts([...posts, ...response.data]);
      setTotalRows(response.pagination._totalRows);
    })();
  }, [page]);
}

return (
    <div>
      <InfiniteScroll
        loader={<p>loading...</p>}
        className="w-[800px] mx-auto my-10"
        fetchMore={() => setPage((prev) => prev + 1)}
        hasMore={posts.length < totalRows}
        endMessage={<p>You have seen it all</p>}
      >
        {posts.map((post, index) => (
          <div
            className="rounded-xl shadow-md mb-8 flex items-center p-5"
            key={index}
          >
            <img src={post.imageUrl} className="rounded-full w-14 h-14" />
            <div className="ml-5">
              <h3 className="font-medium">{post.author}</h3>
              <h1 className="font-bold text-xl">{post.title}</h1>
              <p>{post.description}</p>
            </div>
          </div>
        ))}
      </InfiniteScroll>
    </div>
  );
}

Cách thức hoạt động của component InfiniteScroll là khi cuộn đến cuối sẽ gọi hàm fetchMore để setPage tăng lên 1, lúc này useEffect sẽ chạy lại và fetch posts page tiếp theo để set và posts.

import React, { useEffect, useRef } from "react";

const InfiniteScroll = ({
  children,
  loader,
  fetchMore,
  hasMore,
  endMessage,
  className,
}) => {
  const pageEndRef = useRef(null);
  useEffect(() => {
    if (hasMore) {
      const observer = new IntersectionObserver((entries) => {
        if (entries[0].isIntersecting) { // kiểm tra element có nằm trong viewport không?
          fetchMore();
        }
      });

      if (pageEndRef.current) {
        observer.observe(pageEndRef.current);
      }

      return () => {
        if (pageEndRef.current) {
          observer.unobserve(pageEndRef.current);
        }
      };
    }
  }, [hasMore]);
  return (
    <div className={className}>
      {children}

      {hasMore ? <div ref={pageEndRef}>{loader}</div> : endMessage}
    </div>
  );
};

export default InfiniteScroll;

Đây là mặt mũi ứng dụng của chúng ta.

i1.png

Khi cuộn đến cuối trang.

i2.png

Khi ở page cuối.

i3.png

Tạm kết

Vậy là chúng ta đã xây dựng thành công Infinite Scroll component cho ứng dụng React cơ bản. Mặc dù giao diện còn sơ sài nhưng hy vọng sẽ giúp ích được cho các bạn. Cảm ơn các bạn đã đọc bài viết.

0Bình luận

Bài viết liên quan

thumbnail
avatar

Huy Pham

19/03/2022|6 phút đọc

React Hooks là gì? Các hooks thường dùng trong ReactJS?

Trong bài viết này chúng ta sẽ cùng nhau tìm hiểu về React Hooks và các hooks thường dùng trong ReactJS.

thumbnail
avatar

Huy Pham

21/03/2022|3 phút đọc

Custom hooks là gì ? Xây dựng hook useWindowSize và useDebounce trong ReactJS.

Khi làm việc với ReactJS chắc hẳn bạn không còn xa lạ với các hooks như useState, useRef, useEffect,… Ngoài các hooks có sẵn, bạn ...

thumbnail
avatar

Huy Pham

21/03/2022|1 phút đọc

Refresh Jwt token với Axios Interceptors

Trong bài viết này, mình sẽ hướng dẫn các bạn sử dụng Axios Interceptors để tự động làm mới access token từ refresh token trong jw...

author

Huy Pham

Software Engineer

Insanity is doing the same thing, over and over again, but expecting different results.

Các thẻ đề xuất