JavaScript >> Javascript 文檔 >  >> React

如何使用 Next.js 在 React 中構建全選列表組件

如何在 Next.js 應用程序中使用 React 構建全選列表組件。

開始使用

對於本教程,我們將使用 CheatCode Next.js Boilerplate 為我們的工作提供一個起點。首先,克隆樣板:

終端

git clone https://github.com/cheatcode/nextjs-boilerplate.git

接下來,cd 進入項目並安裝其依賴項:

終端

cd nextjs-boilerplate && npm install

接下來,添加依賴faker 我們將使用它為我們的全選列表生成一些真實的測試數據:

終端

npm i faker

最後,啟動應用程序:

終端

npm run dev

應用啟動並運行後,我們就可以開始了。

構建基礎組件

首先,我們將創建一個基本的 React 組件。因為我們的 UI 相當簡單,所以我們將在 React 中使用函數組件模式:

/pages/users/index.js

import React, { useState } from "react";

const Users = () => {
  const [users] = useState([]);
  const [selectedUsers, setSelectedUsers] = useState([]);

  return (
    <div className="responsive-table">
      <table className="table">
        <thead>
          <tr>
            <th>
              <input
                type="checkbox"
              />
            </th>
            <th className="text-left">Name</th>
            <th className="text-left">Email Address</th>
            <th className="text-center">Last Seen</th>
          </tr>
        </thead>
        <tbody>
          {users.map(({ _id, name, emailAddress, lastSeen }) => {
            return (
              <tr key={_id}>
                <td>
                  <input
                    type="checkbox"
                    value={_id}
                  />
                </td>
                <td className="text-left">{name}</td>
                <td className="text-left">{emailAddress}</td>
                <td className="text-center">{lastSeen}</td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
};

Users.propTypes = {};

export default Users;

在這裡,我們設置了一個 React 組件,它將渲染一個 <table></table> 的用戶,每個用戶都有一個複選框,我們可以使用它在他們的行的第一列中將他們標記為選中。在 <thead></thead> 在表格中,我們添加一個 <input type="checkbox" /> 這將作為整個列表的“全選”複選框。

在我們組件的頂部,我們使用 useState() 來自 React 的鉤子函數來創建兩個動態值:users 的列表 我們將渲染到我們的 <tbody></tbody> 然後是 selectedUsers 的列表 我們將使用它來標記表格中的複選框,以指定當前在 UI 中選擇了哪些用戶。

現在,我們將它們的默認值設置為一個空數組([] 我們傳遞給 useState() )。接下來,要實際顯示我們列表中的一些用戶,我們將學習如何使用 faker 動態生成一些測試數據 我們之前安裝的依賴項。

生成測試用戶列表

在我們的 Users 之外 組件函數,讓我們添加一個新變量,testUsers

/pages/users/index.js

import React, { useState } from "react";
import faker from 'faker';
import { monthDayYearAtTime } from "../../lib/dates";

const testUsers = [...Array(100)].map((item, index) => {
  return {
    _id: `user_${index}`,
    name: faker.name.findName(),
    emailAddress: faker.internet.email(),
    lastSeen: monthDayYearAtTime(faker.date.past()),
  };
});

const Users = () => {
  const [users] = useState(testUsers);
  const [selectedUsers, setSelectedUsers] = useState([]);

  return (
    <div className="responsive-table">
      <table className="table">
        <thead>
          <tr>
            ...
          </tr>
        </thead>
        <tbody>
          {users.map(({ _id, name, emailAddress, lastSeen }) => {
            return (
              <tr key={_id}>
                ...
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
};

Users.propTypes = {};

export default Users;

在我們文件的頂部,我們導入了兩個東西:faker 來自 faker 我們之前安裝的依賴項和我們使用的樣板中內置的輔助函數 monthDayYearAtTime 這將幫助我們為每個用戶生成一個人性化的“最後一次看到”日期。

接下來,我們添加了一個新變量 testUsers 它被設置為一個空數組 [] 包含語句 ...Array(100) .在這裡,... 在 JavaScript 中被稱為擴展運算符。它採用緊隨其後的值——這裡是 Array(100) ——並且將其傳播出去 在父上下文中,或者在本例中是我們的空數組。

Array(100) 這裡的部分是使用 JavaScript Array 的巧妙技巧 函數創建一個包含 100 個元素的數組。通過傳遞數字 100,我們將返回一個 100 undefined 的數組 價值觀。每個 undefined value 在 JavaScript 中被識別為一個值,這意味著,如果我們 .map() 像我們在這裡一樣在那個數組上,我們可以處理那些 undefined 諸如佔位符之類的值並返回一個 real .map() 中的值 函數的回調。

在這裡,我們就是這樣做的,返回一個對象來替換 undefinedArray(100) 創建 .在每個對像上,我們添加一個 _id 等於 user_ 與當前數組索引(0-99 之間的某個數字)連接。接下來,使用 faker 我們在頂部導入的庫,我們使用 faker.name.findName() 為用戶生成一個名稱 用 faker.internet.email() 取回全名字符串和電子郵件地址 .

接下來,我們設置一個 lastSeen 時間戳(主要是為了好玩並使我們的示例更具體),再次使用 faker 使用 faker.date.past() 獲取過去的隨機日期 .我們將該隨機日期傳遞給 monthDayYearAtTime() 我們導入的函數將我們生成的日期轉換為人類可讀的字符串。

最後,使用我們的 testUsers 生成的值,我們替換 [] 我們傳遞給 useState() users 的定義 使用我們的新 testUsers 列出 多變的。現在,當我們渲染我們的組件時,我們應該會在屏幕上看到我們的測試用戶列表。

選擇單個用戶

現在我們有了用戶列表,我們可以實現用戶選擇。我們的目標是做到這一點,以便我們可以做以下兩件事之一:

  1. 一次選擇和取消選擇單個用戶。
  2. 一次選擇或取消選擇所有用戶。

為了處理第一個選項,我們將修改 <input type="checkbox" /> 包括一個 onChange 處理程序和設置其 checked 的方法 狀態:

/pages/users/index.js

import React, { useState } from "react";
import faker from "faker";
import { monthDayYearAtTime } from "../../lib/dates";

const testUsers = [...Array(100)].map((item, index) => { ... });

const Users = () => {
  const [users] = useState(testUsers);
  const [selectedUsers, setSelectedUsers] = useState([]);

  const handleSelectUser = (event) => {};

  return (
    <div className="responsive-table">
      <table className="table">
        <thead>
          ...
        </thead>
        <tbody>
          {users.map(({ _id, name, emailAddress, lastSeen }) => {
            return (
              <tr key={_id}>
                <td>
                  <input
                    type="checkbox"
                    value={_id}
                    checked={selectedUsers.includes(_id)}
                    onChange={handleSelectUser}
                  />
                </td>
                ...
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
};

Users.propTypes = {};

export default Users;

在這裡,查看 <input type="checkbox" /> 在每個用戶行的開頭呈現,我們添加了兩個屬性:checkedonChange .

對於 checked ,我們將它設置為一個 JavaScript 表達式,它接受我們的 selectedUsers 狀態值,並使用 JavaScript 數組 .includes() 方法,檢查 _id 我們當前在列表中映射的用戶。如果他們的 _id 出現在該數組中,這意味著他們是選定的用戶,或者,他們的複選框應該顯示為“選中”。

接下來,對於 onChange ,我們傳遞了一個我們在 return 上方存根的函數 名為 handleSelectUser 的語句 .每當選中或取消選中復選框時,都會調用此函數。現在讓我們設置它以實際處理管理用戶的選定狀態。

/pages/users/index.js

import React, { useState } from "react";
import faker from "faker";
import { monthDayYearAtTime } from "../../lib/dates";

const testUsers = [...Array(100)].map((item, index) => { ... });

const Users = () => {
  const [users] = useState(testUsers);
  const [selectedUsers, setSelectedUsers] = useState([]);

  const handleSelectUser = (event) => {
    const userId = event.target.value;

    if (!selectedUsers.includes(userId)) {
      setSelectedUsers([...selectedUsers, userId]);
    } else {
      setSelectedUsers(
        selectedUsers.filter((selectedUserId) => {
          return selectedUserId !== userId;
        })
      );
    }
  };

  return (
    <div className="responsive-table">
      <table className="table">
        <thead>
         ...
        </thead>
        <tbody>
          {users.map(({ _id, name, emailAddress, lastSeen }) => {
            return (
              <tr key={_id}>
                <td>
                  <input
                    type="checkbox"
                    value={_id}
                    checked={selectedUsers.includes(_id)}
                    onChange={handleSelectUser}
                  />
                </td>
                ...
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
};

Users.propTypes = {};

export default Users;

查看handleSelectUser 函數,我們首先接收 onChange 事件對像作為參數,使用它來檢索 _id 被選中的複選框屬於 event.target.value 的用戶 並將其存儲在變量 const userId 中 .

接下來,我們的實際工作。請記住,有兩種情況需要考慮:

  1. 用戶沒有 選中了他們的複選框,需要將其添加到 selectedUsers 數組。
  2. 用戶的複選框已被選中,需要移除selectedUsers 數組。

在這裡,我們就是這樣做的。對於第一種情況,我們檢查是否 selectedUsers 已經 .includes() userId 我們從 event.target.value 中提取 .如果是不是 ,我們使用 setSelectedUsers 我們從 useState() 返回的方法 , 傳遞一個數組,其第一個值為 ... 現有selectedUsers的傳播 和 userId 的第二個值 我們要添加。反過來,我們設置 selectedUsers 數組 返回狀態,包括 userId 我們檢查了。

對於第二種情況——這裡,在 else 聲明——我們調用 setSelectedUsers 再次,但這次使用 JavaScript .filter() 過濾我們的 selectedUsers 的方法 數組,不包括選中的 userId 從數組。這裡,selectedUserId !== userId 只會評估為 true 如果 userId 不是 匹配 selectedUserId 當前在 .filter() 中循環 .

因為我們將它傳遞給 setSelectedUsers() ,我們將得到過濾後的 selectedUsers 運行時設置為狀態。

選擇所有用戶

接下來,選擇所有用戶需要類似的方法,但稍微簡單一點……

/pages/users/index.js

import React, { useState } from "react";
import faker from "faker";
import { monthDayYearAtTime } from "../../lib/dates";

const testUsers = [...Array(100)].map((item, index) => { ... });

const Users = () => {
  const [users] = useState(testUsers);
  const [selectedUsers, setSelectedUsers] = useState([]);

  const handleSelectAllUsers = () => {
    if (selectedUsers.length < users.length) {
      setSelectedUsers(users.map(({ _id }) => _id));
    } else {
      setSelectedUsers([]);
    }
  };

  const handleSelectUser = (event) => { ... };

  return (
    <div className="responsive-table">
      <table className="table">
        <thead>
          <tr>
            <th>
              <input
                type="checkbox"
                checked={selectedUsers.length === users.length}
                onChange={handleSelectAllUsers}
              />
            </th>
            <th className="text-left">Name</th>
            <th className="text-left">Email Address</th>
            <th className="text-center">Last Seen</th>
          </tr>
        </thead>
        <tbody>
          {users.map(({ _id, name, emailAddress, lastSeen }) => {
            return (
              <tr key={_id}>
                ...
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
};

Users.propTypes = {};

export default Users;

因為我們的目標是選擇全部 我們的用戶,首先,在 <input type="checkbox" /> 在我們的 <thead></thead> ,我們設置checked 屬性等於 selectedUsers.length === users.length .如果這是真的,這意味著我們已經選擇了所有可用的用戶。

同樣,就像我們之前看到的,我們添加了一個 onChange 屬性設置為一個函數,這次定義了一個名為 handleSelectAllUsers 的新函數 .

查看該函數,就像我們在必須處理未檢查 -> 已檢查狀態以及已檢查 -> 未檢查狀態之前所學的那樣。在這裡,對於第一種情況,如果 selectedUsers.length 小於 users.length ,我們setSelectedUsers 等於 .map() 創建的新數組 遍歷我們的 users 數組,摘下 _id 每個用戶的字段。這會將我們所有用戶的 _id 進入 selectedUsers ,這意味著 selectedUsers.includes(userId) 每個用戶旁邊將是 true,將用戶顯示為已選中。

接下來,在 else 語句,這裡的逆操作就像調用 setSelectedUsers() 一樣簡單 , 傳遞一個空數組 [] 這表示當前沒有選擇任何用戶。

總結

在本教程中,我們學習瞭如何使用 React.js 構建全選組件。我們學習瞭如何定義一個 React 組件來呈現一個動態生成的用戶表,在每個用戶旁邊有一個用於選擇的複選框,在該表的頂部有一個“全選”複選框。

我們還學習瞭如何編寫兩個函數:一個用於選擇和取消選擇單個用戶,一個用於選擇和取消選擇所有用戶。


Tutorial JavaScript 教程
  1. 使其可訪問:處理 Angular 中的表單錯誤

  2. 如何讓等待ajax完成

  3. 永不放棄

  4. 獲取Node中的當前文件夾

  5. 簡單的問題 Vanilla JS 顯示不匹配的按鈕

  6. 幫助! Ionic 多次單擊同一選項卡後,後退按鈕無法正常工作。

  7. 2012 年排名前 100 的 JQUERY 插件(第 2/5 部分)

  1. A-Frame 資產管理系統阻止 JavaScript 代碼

  2. 開發說明 8JAN2021

  3. JavaScript 101-#5 – 函數 Pt1

  4. 如何:在 React 中啟動和停止計數器

  5. 使用 Esbuild 捆綁 Figma 插件

  6. DevTools 中的新功能(Chrome 85)

  7. 向 getRange() 添加變量

  1. 將 SendGrid 與 Next.js 集成 :)

  2. WordPress 的 5 個 Node.js 替代品

  3. 哪種編程語言最適合區塊鏈?

  4. 你絕對應該知道的 11 個高級 React 面試問題(附詳細答案)