You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js TypeScript实现:勾选表格行联动外部全选复选框

在 Next.js TypeScript 中实现表格行勾选联动全选框

以下是符合需求的实现方案,通过 React 状态管理跟踪选中行状态,实现表格行与外部全选框的联动:

核心思路

  1. 用状态存储已选中行的ID集合,避免直接操作DOM导致的状态不一致
  2. 根据选中行的数量动态推导全选框的勾选状态
  3. 行复选框的勾选/取消操作同步更新选中行集合

完整代码示例

'use client'; // Next.js 13+ App Router 需添加该指令

import { useState } from 'react';

// 定义表格数据类型,保证类型安全
interface TableRowData {
  id: string;
  name: string;
  email: string;
}

export default function SelectableTable() {
  // 模拟表格数据源
  const tableData: TableRowData[] = [
    { id: '1', name: '张三', email: 'zhangsan@example.com' },
    { id: '2', name: '李四', email: 'lisi@example.com' },
    { id: '3', name: '王五', email: 'wangwu@example.com' },
  ];

  // 存储已选中的行ID
  const [selectedRowIds, setSelectedRowIds] = useState<string[]>([]);

  // 处理单行复选框的勾选/取消事件
  const handleRowCheckboxChange = (rowId: string) => {
    setSelectedRowIds(prev => {
      if (prev.includes(rowId)) {
        // 取消勾选:移除当前行ID
        return prev.filter(id => id !== rowId);
      } else {
        // 勾选:添加当前行ID
        return [...prev, rowId];
      }
    });
  };

  // 处理全选框的勾选/取消事件(可选,用于反向控制所有行)
  const handleSelectAllChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setSelectedRowIds(
      e.target.checked ? tableData.map(row => row.id) : []
    );
  };

  return (
    <div className="p-4">
      {/* 外部全选复选框 */}
      <div className="mb-4">
        <label className="flex items-center gap-2">
          <input
            type="checkbox"
            {/* 需求1:只要有任意一行被勾选,全选框就勾选 */}
            checked={selectedRowIds.length > 0}
            {/* 需求2:如果是「所有行都被勾选时才勾选全选框」,替换为下面这行 */}
            {/* checked={selectedRowIds.length === tableData.length} */}
            onChange={handleSelectAllChange}
          />
          Select all
        </label>
      </div>

      {/* 带复选框的表格 */}
      <table className="border-collapse w-full">
        <thead>
          <tr className="border-b">
            <th className="p-2 text-left">选择</th>
            <th className="p-2 text-left">姓名</th>
            <th className="p-2 text-left">邮箱</th>
          </tr>
        </thead>
        <tbody>
          {tableData.map(row => (
            <tr key={row.id} className="border-b">
              <td className="p-2">
                <input
                  type="checkbox"
                  checked={selectedRowIds.includes(row.id)}
                  onChange={() => handleRowCheckboxChange(row.id)}
                />
              </td>
              <td className="p-2">{row.name}</td>
              <td className="p-2">{row.email}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

关键说明

  • 状态联动逻辑:全选框的checked属性完全由selectedRowIds推导,无需额外维护独立的全选状态,避免状态不同步问题
  • Next.js 适配:使用App Router时必须添加'use client'指令,确保客户端状态逻辑正常运行
  • 异步数据兼容:如果表格数据从API异步获取,只需在数据加载完成后更新tableData,状态逻辑无需修改
  • 类型安全:通过TypeScript接口定义数据结构,避免类型错误

内容的提问来源于stack exchange,提问作者Deepak W3Dev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 02:55:28