reactjs React表中的冒泡选择

gudnpqoy  于 2023-05-22  发布在  React
关注(0)|答案(4)|浏览(117)

我试图将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指南构建了表选择,但它们似乎没有涵盖如何可靠地获取所选行。

siotufzp

siotufzp1#

虽然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 Package 在useCallback中。这与使用react-table文档所概述的记忆一起解决了这个问题。

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

svgewumm2#

我没有得到一个无限循环。你在问题中提到的沙盒文档,我实现了你所要求的,一切都很好。请看一下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
jchrr9hc

jchrr9hc3#

以上这些(或互联网上的其他任何地方)对我都不起作用,但以下是我所做的。我可以想象,有很多人问过关于React Table v7的同样问题,在React Table的版本8中,状态,特别是与选择有关的状态,已经被解决了。但无论如何,这是唯一的变通办法,为我工作,松散的基础上,这个codesandbox
//父组件
1.我使用了一个useCallback钩子来防止我的setSelectedRows(你的setSelection)函数作为一个新函数传递给子函数,并启动多个渲染。
1.我传入了一个初始状态,将React Table的selectedRowIds与父对象的selectedRows设置为:

const ParentDoingParentyThings = () => {
  const [selectedRows, setSelectedRows] = React.useState({});
  const handleSelection = React.useCallback((value) => {
    setSelectedRows(value);   
    }, []); 

return (
  <Table
        data={tableData}
        setSelectedRows={handleSelection}
        initialState={{ sortBy: [{ id: 'totalSeries', desc: true }], selectedRowIds: selectedRows }}
        ...
      />
  )
}

//和table/孩子然后!...
1.我使用了React Table中一个鲜为人知的函数useMountedLayoutEffect。不要问我它做什么的细节,但它的工作原理,这就是它所做的。
1.然后我从RT的selectedRowIds状态
1.我使用RT的useMountedLayoutEffect函数就像使用useEffect一样

import {
  ...
  useMountedLayoutEffect,
} from 'react-table';

export const Table = ({
  data,
  setSelectedRows,
  initialState,
  ...
}: Props) => {
  ...
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow,
    state: { selectedRowIds },
  } = useTable(
    {
      data: tableData,
      initialState,
      ...
    },
    useSortBy,
    useRowSelect,
  );

  useMountedLayoutEffect(() => {
    setSelectedRows && setSelectedRows(selectedRowIds);
  }, [setSelectedRows, selectedRowIds]);

  return (
    <table {...getTableProps()} className={className}>
      ...
    </table>
i2byvkas

i2byvkas4#

使用React.useMemo定义列和/或数据,以避免无限循环。

const columns = React.useMemo(
  () => [
    {
      Header: 'Column 1',
      accessor: 'col1', // accessor is the "key" in the data
    },
    {
      Header: 'Column 2',
      accessor: 'col2',
    },
  ],
  []
)

相关问题