在 React 中實現原生分頁

Irakli Tchigladze 2022年5月18日
在 React 中實現原生分頁

React 是一個用於構建現代單頁應用程式的 JavaScript 庫。SPA 以其速度和卓越的使用者體驗而聞名。但是,實現提供出色 UX 的功能需要付出很多努力。

分頁是這些功能之一,對於一些包含大量資料的應用程式來說是必不可少的。

無論你的應用程式有多複雜,分頁都可以讓你確保網站上的頁面沒有資訊過多。分頁將使使用者能夠輕鬆訪問內容。

例如,如果你的部落格有很多帖子,使用者可能需要一段時間才能找到幾年前的特定帖子。當有分頁功能並且每個頁面都有特定數量的帖子時,這更容易做到。

我們可以在後端或前端進行分頁。本文旨在討論在 React 中原生實現分頁功能。

在 React 中實現原生分頁

要在 React 中實現原生解決方案,我們需要使用狀態。例如,我們需要一個狀態變數 currentPage 來儲存一個整數來指定應該顯示哪些專案批次。

我們還將有一個狀態變數來儲存每個頁面上顯示的專案數。我們可以擁有固定數量的專案,而不是將這些資訊儲存在變數中。

但是,如果我們想改變每頁顯示的專案數或者讓使用者改變,最好把它儲存在 state 中。最後,我們應該有一個狀態變數來儲存要顯示的專案。

我們來看一個實際的例子:

import "./styles.css";
import { useState } from "react";
export default function App() {
    const [items, setItems] = useState([
        "item 1",
        "item 2",
        "item 3",
        "item 4",
        "item 5",
        "item 6",
        "item 7",
        "item 8",
        "item 9",
        "item 10"
    ]);
    const [currentPage, setCurrentPage] = useState(1);
    const [todosPerPage, setTodosPerPage] = useState(3);
    return (
        <div className="App">
        </div>
    );
}

在此程式碼示例中,我們匯入 useState 掛鉤並設定三個狀態變數:

  • items 來儲存我們需要顯示的專案,
  • currentPage 儲存需要顯示的頁面的整數值(預設為 1),以及
  • todosPerPage 儲存每頁上的專案數。

現在,讓我們在程式碼中新增一點邏輯。

由於我們在每個頁面上顯示一定數量的專案,並且使用者可以在頁面之間切換,因此我們需要弄清楚需要顯示哪些專案。我們有十個專案,每頁有三個專案,所以我們將有四頁。

第一頁將顯示第一個、第二個和第三個專案,依此類推。我們可以硬編碼應該為每個頁面顯示哪些專案,但是開發一個可以處理任意數量專案的系統要明智得多。

我們來看看邏輯:

const [currentPage, setCurrentPage] = useState(1);
const [todosPerPage, setTodosPerPage] = useState(3);
const lastTodoInView = currentPage * todosPerPage;
const firstTodoInView = lastTodoInView - todosPerPage;

lastTodoInViewfirstTodoinView 這兩個變數表示陣列中的索引,這應該是在特定頁面上顯示專案的邊界。例如,對於第一頁,假設 todosPerPage 設定為三,邊界將是:

最後一個:1 (currentPage) * 3 (todosPerPage) = 3

第一個:3 (lastTodoInView) - 3 (todosPerPage) = 0

請注意,在 JavaScript 中,陣列的第一項索引為 0,因此要顯示在第一頁上的項將具有 0、1 和 2 索引,直到它們達到 3。最後一個陣列索引不包含在內,因為如何 .slice() 方法是設計好的,所以我們的頁面不會包含索引 3 上的專案。

接下來,我們可以使用 .slice() 方法來提取每個頁面上顯示的特定值。

const todosForDisplay = items.slice(firstTodoInView, lastTodoInView);

這個方法有兩個引數,陣列項的開始和結束索引。起始索引是包含的,這意味著如果第一個引數為 0,則一旦執行該方法,新返回的陣列將包含第一項。

結束索引不包含在內,這意味著如果第二個引數為 3,則返回的陣列將在索引 2 處停止。

然後,我們可以建立一個變數來儲存從切片陣列生成的所有 JSX 元素。

const renderItems = todosForDisplay.map((todo, index) => {
    return <li key={index}>{todo}</li>;
});

建議將 key 屬性設定為唯一值,以便 React 可以在內部跟蹤各個節點。

稍後,我們將新增程式碼以允許使用者更改 currentPage 變數,或者簡單地說,從一個頁面轉到另一個頁面。我們還可以新增更新每個頁面上顯示的專案數量的功能,一切都會正常工作。

接下來,我們必須生成一個頁碼陣列。隨著陣列中專案數量的增加,頁數也應該增加。

例如,目前,我們的陣列有 10 個專案和 4 個頁面來顯示它們。如果我們再新增 5 個專案,我們需要計算要顯示它們的頁面數。

以下是計算顯示所有專案所需的頁數的邏輯:

const pageNumbers = [];
for (let n = 1; n <= Math.ceil(items.length / todosPerPage); n++) {
    pageNumbers.push(n);
}

在這裡,我們生成了一個簡單的 for 迴圈。我們從初始值 1 開始,並將其新增到 pageNumbers 陣列中。

我們新增越來越多的頁面,直到有足夠的頁面來顯示每個專案。然後我們必須生成要在應用程式中顯示的實際頁碼。

為此,我們將在 pageNumbers 陣列上使用 .map() 方法。讓我們看一下程式碼:

const renderPageNumbers = pageNumbers.map((number, index) => {
    return <li key={index}>{number}</li>;
});

這將生成與頁碼對應的所有 JSX 元素。我們必須建立一個事件處理程式以允許使用者從一個頁面移動。

這很容易實現,因為 useState() 鉤子提供了一個簡單的更新函式來更新值。我們要處理點選事件,事件處理函式可以很簡單:

const renderPageNumbers = pageNumbers.map((number, index) => {
    return <li onClick={() => setCurrentPage(number)} key={index}>
        {number}
    </li>
});

最後,我們簡單的分頁系統就完成了。你可以檢視 CodeSandbox 上的演示,瞭解所有內容如何組合在一起。

Irakli Tchigladze avatar Irakli Tchigladze avatar

Irakli is a writer who loves computers and helping people solve their technical problems. He lives in Georgia and enjoys spending time with animals.

LinkedIn