如何 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 元素。事件在不同层中冒泡,所有元素都可能对其做出反应。但是你确实想阻止它在你的情况下冒泡。
我已经将我的 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 元素。事件在不同层中冒泡,所有元素都可能对其做出反应。但是你确实想阻止它在你的情况下冒泡。