Bạn đã bao giờ ghé thăm trang web hay ứng dụng tải và hiện nhiều nội dung hơn khi bạn cuộn màn hình chưa? Đó chính là infinite scroll - cuộn vô tận.
Infinite scroll là một kỹ thuật phổ biến, có thể giúp việc duyệt nhiều nội dung trên web dễ dàng hơn. Nó cũng góp phần tạo ra trải nghiệm người dùng mượt mà, nhất là trên thiết bị mobile.
Triển khai Infinite Scroll trong React.js
Bạn có thể làm Infinite scroll trong ReactJS theo một số cách. Đầu tiên là dùng library như react-infinite-scroll-component. Thành phần của thư viện này kích hoạt một sự kiện bất cứ khi nào người dùng cuộn tới phần dưới cùng của trang. Sau đó, bạn có thể dùng sự kiện này làm gợi ý để tải thêm nội dung.
Cách khác để triển khai cuộn vô tận trong React là qua các hàm sẵn có. Một trong số những hàm như thế là “componentDidMount,” mà React gọi khi lần đầu tiên nó gắn vào một thành phần.
Bạn có thể dùng hàm này để tải lô dữ liệu đầu tiên, được theo sau bởi hàm “componentDidUpdate” để tải dữ liệu tiếp theo khi người dùng cuộn xuống dưới.
Bạn cũng có thể dùng các hook React để thêm tính năng cuộn vô tận.
Dùng library react-infinite-scroll-component
Bạn có một số cách để dùng react-infinite-scroll-component.
Cài đặt react-infinite-scroll-component
Để bắt đầu sử dụng, đầu tiên, bạn cần cài đặt nó qua npm:
React.js
Nhập react-infinite-scroll-component vào React
Sau khi cài đặt, bạn cần nhập library cuộn vô tận vào thành phần React.
import React from 'react'
import InfiniteScroll from 'react-infinite-scroll-component'
class App extends React.Component {
constructor() {
super()
this.state = {
items: [],
hasMore: true
}
}
componentDidMount() {
this.fetchData(1)
}
fetchData = (page) => {
const newItems = []
for (let i = 0; i < 100; i++) {
newItems.push(i )
}
if (page === 100) {
this.setState({ hasMore: false })
}
this.setState({ items: [...this.state.items, ...newItems] })
}
render() {
return (
<div>
<h1>Infinite Scroll</h1>
<InfiniteScroll
dataLength={this.state.items.length}
next={this.fetchData}
hasMore={this.state.hasMore}
loader={<h4>Loading...</h4>}
endMessage={
<p style={{ textAlign: 'center' }}>
<b>Yay! You have seen it all</b>
</p>
}
>
{this.state.items.map((item, index) => (
<div key={index}>
{item}
</div>
))}
</InfiniteScroll>
</div>
)
}
}
export default App
Code này bắt đầu bằng cách nhập React và thành phần InfiniteScroll từ library react-infinite-scroll-component. Sau đó, nó tạo một thành phần trạng thái và khởi tạo nó bằng mảng items trống và flag hasMore đặt sang True.
Đặt các tham số
Trong phương thức vòng đời componentDidMount, bạn phải gọi fetchData với tham số page đặt sang 1. fetchData gọi API để tìm nạp dữ liệu. Ví dụ react-infinite-scroller này tạo một số dữ liệu giả và một mảng chứa 100 mục.
Trên tham số trang đạt tới 100, vì không có nhiều mục tồn tại, bạn có thể đặt flag hasMore sang False. Điều này ngăn thành phần InfiniteScroll thực hiện thêm các cuộc gọi API. Cuối cùng, đặt trạng thái bằng dữ liệu mới.
Phương thức kết xuất dùng thành phần InfiniteScroll và truyền vào một số thuộc tính. Thuộc tính dataLength thiết lập độ dài của mảng mục. Thuộc tính sau được đặt sang phương thức fetchData. Thuộc tính hasMore được đặt bằng với flag hasMore.
Thuộc tính loader làm thành phần này hiện nội dung của nó dưới dạng chỉ báo đang tải. Tương tự, nó sẽ hiện endMessage dưới dạng thông báo khi đã tải xong toàn bộ dữ liệu.
Bạn có thể chuyển các thuộc tính khác sang thành phần Infinite, nhưng chúng là những phần tử bạn thường dùng nhất.
Các hàm có sẵn
React cũng có một số phương thức sẵn có mà bạn có thể dùng để triển khai InfiniteScroll.
Phương thức đầu tiên là componentDidUpdate. React gọi phương thức này sau khi nó cập nhật một thành phần. Bạn có thể dùng cách này để kiểm tra xem liệu người dùng đã cuộn xuống dưới cùng của trang hay chưa. Nếu đúng như vậy, nó tải nhiều dữ liệu hơn.
Phương thức thứ hai là scroll, mà React gọi khi người dùng cuộn. Bạn có thể dùng phương thức này để theo dõi vị trí cuộn. Bạn có thể tải nhiều dữ liệu hơn nếu người dùng đã cuộn xuống dưới cùng của trang.
Đây là ví dụ cuộn vô tận trong React mà cho bạn biết cách dùng những phương thức trên:
import React, {useState, useEffect} from 'react'
function App() {
const [items, setItems] = useState([])
const [hasMore, setHasMore] = useState(true)
const [page, setPage] = useState(1)
useEffect(() => {
fetchData(page)
}, [page])
const fetchData = (page) => {
const newItems = []
for (let i = 0; i < 100; i++) {
newItems.push(i)
}
if (page === 100) {
setHasMore(false)
}
setItems([...items, ...newItems])
}
const onScroll = () => {
const scrollTop = document.documentElement.scrollTop
const scrollHeight = document.documentElement.scrollHeight
const clientHeight = document.documentElement.clientHeight
if (scrollTop + clientHeight >= scrollHeight) {
setPage(page + 1)
}
}
useEffect(() => {
window.addEventListener('scroll', onScroll)
return () => window.removeEventListener('scroll', onScroll)
}, [items])
return (
<div>
{items.map((item, index) => (
<div key={index}>
{item}
</div>
))}
</div>
)
}
export default App
Code này dùng hook useState và useEffect để quản lý trạng thái và hiệu ứng cạnh bên.
Trong hook useEffect, nó gọi fetchData với trang hiện tại. fetchData tạo cuộc gọi API để tìm nạp dữ liệu. Ở ví dụ này, bạn vừa tạo một số dữ liệu giả để minh họa cho kỹ thuật này.
Vòng lặp for điền vào mảng newItems với 100 số nguyên. Nếu tham số trang là 100, nó đặt flag hasMore sang False. Điều này ngăn thành phần cuộn vô tận thực hiện thêm các cuộc gọi API.
Cuối cùng, đặt trạng thái với dữ liệu mới.
Phương thức onScroll theo dõi vị trí cuộn. Bạn có thể tải nhiều dữ liệu hơn nếu người dùng cuộn xuống dưới cùng của trang.
Hook useEffect thêm trình nghe sự kiện cho sự kiện cuộn. Khi sự kiện cuộn khởi động, nó gọi phương thức onScroll.
Ưu và nhược điểm của cuộn vô tận trong React
Ưu điểm:
- Cải thiện giao diện người dùng.
- Trải nghiệm mượt mà hơn, đặc biệt trên thiết bị di động.
- Giảm số lần tải trang.
Nhược điểm:
- Có thể làm người dùng thấy nội dung bị thiếu khi họ không cuộn đủ xa xuống phía dưới màn hình.
Hi vọng bài viết hữu ích với các bạn.