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

react-table选中行后激活对应操作按钮的实现方案

我使用react table创建了一个表格,需求是只有点击行对应的复选框后,该行的按钮才可以正常使用,未勾选时按钮不可交互。我的表格布局如下:

表格布局

我的实现代码如下:

import React, {
  useEffect,
  useImperativeHandle,
  useMemo,
  useRef,
  useState,
} from "react";
import { useDispatch, useSelector } from "react-redux";
import { useTable, useSortBy, usePagination, useRowSelect } from "react-table";
import { Input } from "reactstrap";
import { updateFromCurrency } from "../store/Actions/currencyActions";
import { BuyingModal } from "./BuyingModal";
import { IndeterminateCheckbox } from "./Checkbox";
import { SellingModal } from "./SellingModal";

export const PortfolioTable = () => {
  const portfolio = useSelector((state) => state.portfolioData);
  const dispatch = useDispatch();
  const [fromCurrency, setFromCurrency] = useState("");
  const data = useMemo(() => [...portfolio], [portfolio]);

  useEffect(() => {
    dispatch(updateFromCurrency(fromCurrency));
  }, [fromCurrency]);

  const setCurrency = (ancronym) => {
    setFromCurrency(ancronym);
  };

  const columns = useMemo(
    () => [
      {
        Header: "Acronym",
        accessor: "acronym",
        disableSortBy: true,
      },
      {
        Header: "Name",
        accessor: "name",
      },
      {
        Header: "Amount",
        accessor: (d) => d.totalAsset.toFixed(3),
      },
      {
        width: 300,
        Header: "Trade",
        Cell: ({ row }) => (
          <div className="d-flex justify-content-center">
            <BuyingModal
              buttonLabel="Buy"
              selected={[row.original.acronym, row.original.name]}
            />
            <SellingModal buttonLabel="Sell" />
          </div>
        ),
      },
    ],
    []
  );

  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    prepareRow,
    page,
    rows,
    selectedFlatRows,
    state: { selectedRowIds },
  } = useTable(
    { columns, data },
    useSortBy,
    usePagination,
    useRowSelect,
    (hooks) => {
      hooks.visibleColumns.push((columns) => [
        // 自定义选择列
        {
          id: "selection",
          Header: ({ getToggleAllRowsSelectedProps }) => (
            <div>
              <IndeterminateCheckbox {...getToggleAllRowsSelectedProps()} />
            </div>
          ),

          Cell: ({ row }) => (
            <div>
              <IndeterminateCheckbox {...row.getToggleRowSelectedProps()} />
            </div>
          ),
        },
        ...columns,
      ]);
    }
  );
  return (
    <div className="d-flex flex-column mb-5 mt-5 ms-1 me-2 shadow">
      <table {...getTableProps()} style={{ borderRadius: "15px" }}>
        <thead>
          {headerGroups.map((headerGroup) => (
            <tr {...headerGroup.getHeaderGroupProps()}>
              {headerGroup.headers.map((column) => (
                <th
                  {...column.getHeaderProps(column.getSortByToggleProps())}
                  className="border"
                  style={{
                    background: "#f3f4f6",
                    color: "black",
                    paddingLeft: "12px",
                  }}
                >
                  {column.render("Header")}
                  <span>
                    {column.isSorted ? (column.isSortedDesc ? "🔽" : "🔼") : ""}
                  </span>
                </th>
              ))}
            </tr>
          ))}
        </thead>
        <tbody {...getTableBodyProps()}>
          {page.map((row) => {
            prepareRow(row);
            return (
              <tr
                {...row.getRowProps()}
                onClick={() => setCurrency(row.original.acronym)}
              >
                {row.cells.map((cell) => {
                  return (
                    <td
                      {...cell.getCellProps()}
                      className="border py-2 "
                      style={{
                        textDecorationLine: "none",
                        paddingLeft: "7px",
                      }}
                    >
                      {cell.render("Cell")}
                    </td>
                  );
                })}
              </tr>
            );
          })}
        </tbody>
      </table>
      <pre>
        <code>
          {JSON.stringify(
            {
              selectedRowIds: selectedRowIds,
              "selectedFlatRows[].original": selectedFlatRows.map(
                (d) => d.original
              ),
            },
            null,
            2
          )}
        </code>
      </pre>
    </div>
  );
};

我之前遇到的问题是:不知道如何将selectedRowId作为全局状态传递给Buy或Sell组件,也无法将selectedRowId提取到函数外作为全局状态使用。

解决方案

通过react-table提供的isSelected属性判断行的选中状态,即可实现需求,代码如下:

{
        width: 100,
        Header: "Trade",
        Cell: ({ row }) =>
          row.isSelected ? (
            <div className="d-flex justify-content-center">
              <BuyingModal
                buttonLabel="Buy"
                selected={[row.original.acronym, row.original.name]}
              />
              <SellingModal buttonLabel="Sell" />
            </div>
          ) : (
            <div>
              <button className="btn btn-success m-1">Buy</button>
              <button className="btn btn-danger m-1">Sell</button>
            </div>
          ),
      },

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 21:06:05