提问人:dmikester1 提问时间:10/3/2023 最后编辑:terahertzdmikester1 更新时间:10/8/2023 访问量:125
从较高的组件中取消选择所有行
deselecting all rows from higher component
问:
我正在将 React Table v8 用于我的新 Web 应用程序。我有一个表格,上面有用于选择行的复选框。在组件树中较高位置的组件中,我正在对选定的行执行某些操作,然后我想清除所有选定的行。我在搜索时发现了函数 toggleAllRowsSelected。我尝试将这个“useEffect”添加到我的表组件中。
useEffect(() => {
if (selectedRows.length === 0) {
table.toggleAllRowsSelected(false);
}
}, [selectedRows]);
然后,我从组件树中的组件向上传递了“selectedRows”。 但这会导致连续的运行循环。
我正在像这样创建我的 ReactTable:
const table = useReactTable({
data,
columns,
state: {
sorting,
rowSelection,
globalFilter,
columnFilters
},
onSortingChange: setSorting,
onRowSelectionChange: setRowSelection,
onColumnFiltersChange: setColumnFilters,
onGlobalFilterChange: setGlobalFilter,
enableRowSelection: true,
getCoreRowModel: getCoreRowModel(),
getSortedRowModel: getSortedRowModel(),
getFilteredRowModel: getFilteredRowModel()
// debugTable: true
});
有人知道我如何正确地实现这一目标吗?
基本上,我只想传递一个信号/触发器,以从表本身上方的组件中取消选择表中的所有行。
答:
仅从这段代码中,我无法判断为什么您有一个渲染循环。
但似乎您有 2 个组件,它们都跟踪 RowSelectionState:
- 较高的组件跟踪“selectedRows”
- 下部组件跟踪“rowSelection”
这似乎有问题。一个国家应该有一个单一的事实来源。
- 也许您可以删除“selectedRows”并传递“rowSelection”和“setRowSelection”
- 使用上下文使 “rowSelection” 和 “setRowSelection” 可用于 react table 组件
- 使用类似“Jotai”的东西将 rowSelection 状态存储在 react 之外
如果在关闭“严格模式”时渲染循环消失,则 useEffect 导致了问题。 否则,我会怀疑您设置“selectedRows”和“rowSelection”的方式是错误的
我已经实现了一个 react-table (v8),带有一个按钮来取消选择所有行。
我在父组件中使用了 ref:
const tableRef = React.useRef(null);
之后,我使用 forwardRef 将该 ref 转发到子组件。
//Define the methods required for the parent component to interact with the child component
useImperativeHandle(ref, () => ({
resetSelectedRows: () => toggleAllRowsSelected(false)
}));
...
//In the parent component, we can deselect all rows by applying the following
tableRef.current?.resetSelectedRows();
因此,使用这种方法,您可以解决您提出的问题。
评论
React Tables 通过使用钩子来工作。useReactTable
const [rowSelection, setRowSelection] = React.useState({});
const table = useReactTable({
state: {
rowSelection, // the state holding which rows are selected
},
enableRowSelection: true, //enable row selection for all rows
onRowSelectionChange: setRowSelection, // handles row selection change
// other properties
});
如果选择了第 1 行,则调用该行,并将状态更新为 。setRowSelection
{ 1: true }
有几种方法可以解决您的问题。
方法 1 - 将状态向上移动到父组件
您可以通过将状态提升到父组件来提升到父组件。rowSelection
即将以下代码转移到父组件const [rowSelection, setRowSelection] = React.useState({});
然后像这样将其传递给您的子组件:
<Table rowSelection={rowSelection} setRowSelection={setRowSelection} />
在父组件中,您可以使用将所选行状态重置为空。setRowSelection({})
下面是 CodeSandBox 中的一个示例,演示了上述内容。我的示例由一个包含组件的父组件组成,您可以在父组件中重置 React 表。<App>
<Table>
方法 2 - 使用上下文或状态管理库
为了简单起见,我将使用 React Context。如果表和父组件之间有许多中间组件将重置状态,则需要使用它。您还可以使用其他状态管理库,例如 Zustand 或 React Redux 而不是 Context。
这个想法很简单。由于您已经知道提供了一个函数,它将重置所有选定的行。然后,我们需要做的就是将对象“向上”传递(到父组件)以使用它。table
toggleAllRowsSelected()
table
要使用 React Context 做到这一点,我们首先创建一个 has 作为状态。TableContext
setTable
import { createContext } from 'react';
export const TableContext = createContext({ setTable: null });
在父组件中,我们创建一个状态,并用 包装子组件。我们还提供状态作为默认值。table
<Table>
TableContext.Provider
function App() {
const [table, setTable] = useState();
// other code omitted for brevity
return (
<TableContext.Provider value={{ setTable }}>
<Table />
</TableContext.Provider>
)
在子组件中,我们使用 hook 来读取和获取函数。我们创建 React 表。创建成功后,我们使用 .父组件现在可以访问该对象。useContext
TableContext
setTable
table
setTable
table
function myTable() {
const { setTable } = useContext(TableContext);
const reactTable = useReactTable({
// omitted for brevity
});
useEffect(() => {
if (reactTable) {
setTable(reactTable); // parent component can now access reactTable
}
}, [reactTable, setTable]);
// other code omitted for brevity
}
下面是 Codesandbox 演示 React Context 的示例。
解决此问题的一种方法是在组件中定义一个新函数,该函数负责取消选择所有行。必要时,可以从父组件调用此函数以清除所选行。例如:
const deselectAllRows = () => {
table.toggleAllRowsSelected(false);
}
然后,在父组件中,您可以利用该函数删除所有选定的行:deselectAllRows()
const clearSelectedRows = () => {
// perform some action with the selected rows
// then call the deselectAllRows function
deselectAllRows();
}
<TableComponent rows={rows} clearSelectedRows={clearSelectedRows} />
toggleAllRowsSelected()
函数仅在必要时触发,而不是重复引起循环。
评论