在反应中冒泡选择-table

Bubble up selection in react-table

我试图将我的 react-table 组件中的当前选择传递给父级,以便在发生选择时执行一些逻辑,但我似乎无法找到可靠的方法得到选择。我尝试了以下方法:

function Table({ columns: userColumns, data, setSelection }) {
  const {
      ...,
      selectedFlatRows,
    } = useTable(
      {
        ...
      },
       ...,
      useRowSelect,
      (hooks) => {...})

  useEffect(() => {

      // Bubble up the selection to the parent component
      setSelection(selectedFlatRows.map((row) => row.original));
   }, [selectedFlatRows]);

但是上面只是创建了一个无限循环。我已经根据指南 given in the docs 构建了 table 选择,但它们似乎没有涵盖如何可靠地获取所选行。

我没有得到无限循环。您在问题中提到的沙箱文档,我实现了您的要求,并且一切正常。请查看 codesandbox 和我从沙盒中截取的简短片段。

import React from 'react'
import styled from 'styled-components'
import { useTable, useRowSelect } from 'react-table'

import makeData from './makeData'

function Table({ columns, data, setSelection }) {
  // Use the state and functions returned from useTable to build your UI
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow,
    selectedFlatRows,
    state: { selectedRowIds },
  } = useTable(
    {
      columns,
      data,
    },
    useRowSelect,
    hooks => {
      hooks.visibleColumns.push(columns => [
        // Let's make a column for selection
        {
          id: 'selection',
          // The header can use the table's getToggleAllRowsSelectedProps method
          // to render a checkbox
          Header: ({ getToggleAllRowsSelectedProps }) => (
            <div>
              <IndeterminateCheckbox {...getToggleAllRowsSelectedProps()} />
            </div>
          ),
          // The cell can use the individual row's getToggleRowSelectedProps method
          // to the render a checkbox
          Cell: ({ row }) => (
            <div>
              <IndeterminateCheckbox {...row.getToggleRowSelectedProps()} />
            </div>
          ),
        },
        ...columns,
      ])
    }
  )

  React.useEffect(() => {
    // Bubble up the selection to the parent component
    setSelection(selectedFlatRows.map((row) => row.original));
  }, [setSelection, selectedFlatRows]);

  console.log('selectedFlatRows', selectedFlatRows)

  // Render the UI for your table
  return (
    <>
      <table {...getTableProps()}>
        <thead>
          {headerGroups.map(headerGroup => (
            <tr {...headerGroup.getHeaderGroupProps()}>
              {headerGroup.headers.map(column => (
                <th {...column.getHeaderProps()}>{column.render('Header')}</th>
              ))}
            </tr>
          ))}
        </thead>
        <tbody {...getTableBodyProps()}>
          data here
        </tbody>
      </table>
    </>
  )
}

function App() {
  const [selection, setSelection] = React.useState([]);
  const columns = []

  const data = React.useMemo(() => makeData(10, 3), [])
  console.log('selection', selection)
  return (
    <Styles>
      <Table columns={columns} data={data} setSelection={setSelection} />
    </Styles>
  )
}

export default App

虽然rotimi-best的回答是正确的,但并没有解决我的问题。我有一个包含函数的组件,它需要了解选择。我的结构如下:

<Container> // This container needs to know about the selection.
   <Table
      columns={columns}
      data={data}
      setSelection={(selection) => handleSetSelection(selection)} // Passed down to the table instance
   />
</Container>

解决方案是将顶层 setSelection 包装在 useCallback 中。这与 react-table 文档概述的使用记忆一起解决了这个问题。

Container:
...
const [selection, setSelection] = useState([]);
const selectionCallback = React.useCallback((ids) => setSelection(ids), [
    setSelection,
  ]);