如何 select 特定列中的一行而不触发 React 中整行的 onClick 函数 Table

How to select a row in a specific column without triggering the onClick function for that entire row in React Table

我已经将我的 React Table 设置为当用户单击一行时他们将被带到另一个页面,但现在我在第一列中添加了一个复选框,允许用户拥有该行突出显示,但当我单击该复选框时,它将用户带到另一个页面,因为它触发了单击整行时调用的函数。

我已尝试获取列访问器名称,如果单击的列是第一个,则不会将用户路由到另一个页面,但我无法获取有关选择的列的信息。我花了很多时间查看文档,但无法弄明白。

我真的很感激任何帮助,因为我很难掌握 React Table 一般

RecordTable.js

    import React from "react";
import {
  useTable,
  useFlexLayout,
  useFilters,
  useGlobalFilter,
  useRowSelect
} from "react-table";
import _ from "lodash";
// noinspection ES6CheckImport
import { useHistory } from "react-router-dom";
import Table from "react-bootstrap/Table";

// Define a default UI for filtering
function GlobalFilter({
  preGlobalFilteredRows,
  globalFilter,
  setGlobalFilter
}) {
  return (
    <span>
      <input
        value={globalFilter || ""}
        onChange={e => {
          setGlobalFilter(e.target.value || undefined); // Set undefined to remove the filter entirely
        }}
        placeholder={" Search by any criteria"}
        style={{
          fontSize: "2.0rem",
          width: "100%"
        }}
      />
    </span>
  );
}

const IndeterminateCheckbox = React.forwardRef(
  ({ indeterminate, ...rest }, ref) => {
    const defaultRef = React.useRef();
    const resolvedRef = ref || defaultRef;

    React.useEffect(() => {
      resolvedRef.current.indeterminate = indeterminate;
    }, [resolvedRef, indeterminate]);

    return (
      <>
        <input type="checkbox" ref={resolvedRef} {...rest} />
      </>
    );
  }
);

export const RecordTable = ({ forms }) => {
  //TODO figure out why react-table crashes if forms is not set to data variable below first
  const data = forms;
  let history = useHistory();

 

  const columns = React.useMemo(
    () => [
      {
        Header: "Disclaimer Form Records",
        columns: [
          {
            Header: "First Name", 
          {
            Header: "Time In",
            accessor: "timeIn"
          },
          {
            Header: "Time Out",
            accessor: "timeOut"
          },
          {
            Header: "€ Price",
            accessor: "totalGroupPrice",
            disableFilters: true,
            disableSortBy: true
          }
        ]
      }
    ],
    []
  );

  const defaultColumn = React.useMemo(
    () => ({
      //minWidth: 20,
      maxWidth: 150,
      width: 120
    }),
    []
  );

  const rowOnClick = (rowObject, column) => {
    console.log("rowObject.original: ", rowObject.original);
    console.log("column.id: ", column);
    history.push("/viewform", { ...rowObject.original });
  };



  // Use the state and functions returned from useTable to build your UI
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow,
    state,
    preGlobalFilteredRows,
    setGlobalFilter,
    setHiddenColumns,
  } = useTable(
    {
      columns,
      data,
      defaultColumn
    },
    useFilters,
    useGlobalFilter,
    useFlexLayout,
    useRowSelect,
    hooks => {
      hooks.visibleColumns.push(columns => [
        // Let's make a column for selection
        {
          accessor: "active",
          Header: "Active",
          width: 50,
          maxWidth: 50,
          minWidth: 50,
          Cell: ({ row }) => (
            <div>
              <IndeterminateCheckbox {...row.getToggleRowSelectedProps()} />
            </div>
          )
        },
        ...columns
      ]);
    }
  );

 

  // Render the UI for your table
  return (
    <div>
      <div>Records: {rows.length}</div>
      <GlobalFilter
        preGlobalFilteredRows={preGlobalFilteredRows}
        globalFilter={state.globalFilter}
        setGlobalFilter={setGlobalFilter}
      />

      <div
        style={{
          height: 500,
          border: "2px solid grey",
          borderRadius: "5px",
          overflow: "scroll"
        }}>
        <Table striped bordered hover responsive={"md"} {...getTableProps()}>
          <thead>
            {headerGroups.map(headerGroup => (
              <tr {...headerGroup.getHeaderGroupProps()}>
                {headerGroup.headers.map(column => (
                  <th {...column.getHeaderProps()}>
                    {column.render("Header")}
                  </th>
                ))}
              </tr>
            ))}
          </thead>

          <tbody {...getTableBodyProps()}>
            {rows.map((row, column, i) => {
              prepareRow(row);
              return (
                <tr
                  {...row.getRowProps({
                    onClick: () => rowOnClick(row, column)
                  })}>
                  {row.cells.map(cell => {
                    return (
                      <td {...cell.getCellProps()}>{cell.render("Cell")}</td>
                    );
                  })}
                </tr>
              );
            })}
          </tbody>
        </Table>
      </div>
    </div>
  );
};

您需要在复选框上设置 onClick={e => e.stopPropagation()}

从技术上讲,点击发生在多个元素上。复选框、单元格行等

在 JS 中,事件在顶部元素上创建,然后传播 ('bubbled') 通过位于鼠标光标下的所有 DOM 元素。事件在不同层中冒泡,所有元素都可能对其做出反应。但是你确实想阻止它在你的情况下冒泡。