当父级传递新数据或更新数据时重新渲染 Table 组件

Re-rendering Table component when parent passes new or updated data

我正在从 React Table 6 过渡到 7,它带来了很多新的变化,因为 React Table 7 现在是一个无头的实用程序库,构建有很多很多的钩子。这与 React 有很大不同 Table 6. 我对 hooks 不太熟悉,之前也没有使用过它们(几个月前我已经阅读过它们),但现在有点被迫进入它们的杂草,因为我的应用程序严重依赖这个库。

使用 the examples guide here,我在我的 React 应用程序中设置了一个初始 table,试图将 table 连接到我的应用程序的实时数据,该数据是通过 Axios 获取的。然而,我正在为一个最初的重要功能而苦苦挣扎——让 Table 组件显示/更新我传递给它的数据,但只有在数据发生变化之后[=36] =].

为了让大家更清楚,我创建了以下组件:

import React from 'react';
import { useTable } from 'react-table';

function MyReactTable7Table({ tableData }) {

    // 1. Create Columns
    const columns = React.useMemo(
        () => [
            {
                Header: 'Name',
                columns: [
                    {
                        Header: 'Col Available From Start',
                        accessor: 'conferenceId'
                    },
                    {
                        Header: 'Col Avail After Parent Re-Render',
                        accessor: 'teamMarket'
                    }
                ]
            }
        ],
        []
    );

    // 2. Create Data
    const data = React.useMemo(() => tableData, []);

    // 3. Call Use Table
    const {
        getTableProps,
        getTableBodyProps,
        headerGroups,
        rows,
        prepareRow
    } = useTable({ columns, data });

    // 4. Return the HTML Table
    return (<>
        <table {...getTableProps()}>
            <thead>
                {headerGroups.map(headerGroup => (
                    <tr {...headerGroup.getHeaderGroupProps()}>
                        {headerGroup.headers.map(column => (
                            // Add the sorting props to control sorting. For this example
                            // we can add them into the header props
                            <th {...column.getHeaderProps()}>
                                {column.render('Header')}
                            </th>
                        ))}
                    </tr>
                ))}
            </thead>
            <tbody {...getTableBodyProps()}>
                {rows.map(
                    (row) => {
                        prepareRow(row);
                        return (
                            <tr {...row.getRowProps()}>
                                {row.cells.map(cell => {
                                    return (
                                        <td {...cell.getCellProps()}>{cell.render('Cell')}</td>
                                    );
                                })}
                            </tr>
                        );
                    }
                )}
            </tbody>
        </table>
    </>);
}

export default MyReactTable7Table;

这几乎是直接从示例页面复制的,除了我没有使用模拟数据,而是传递从父组件获取并作为道具传递的数据。问题是:尽管来自父组件的数据确实更新了(最初,获取了一个只有 5 列的瘦 table,然后获取了一个具有 20 列的更大的 table 来替换第一个 table 在父组件状态下),UI 不会在我的网络应用程序上更新。 (我想是因为 table 组件的内部状态没有更新?)

在我的示例中,conferenceId 是获取的最初 5 列中的 1 列,但是 teamMarket 是 20 列之一,但不是 5 初始列之一。虽然父组件获取新数据并重新呈现,但 Table 组件不会更新以在新列中显示新数据。

我正在用这个快速找出钩子和无头组件,并且想遵循使用这个库的最佳实践,因为从文档+示例来看,它似乎是一个非常好的和强大的table React 组件。

编辑

为了快速更新和澄清,父组件触发 2 个单独的异步 Axios 提取以更新同一个父状态变量可能是一个不好的模式。我不确定。正如我提到的,只是为了澄清,第一次获取快速获取数据的瘦版本,而第二次获取获取完整的 table。因为父状态使用新数据数组更新,所以作为 tableData 属性传递给 <MyReactTable7Table /> 的数组也会发生变化。

很难连接到实时,因为错误/问题本身与实时数据未正确更新有关...

您为 useMemo 提供了一个空数组依赖项,这意味着 tableData 的记忆值已创建并分配给 data,并且永远不会更改。您将需要提供依赖性,指示 useMemo 何时应 recalculate/regenerate 该值。

在你的情况下,不需要第二个useMemo

所以删除下面的代码,只使用tableData

const data = React.useMemo(() => tableData, []);

像这样:

const {
        getTableProps,
        getTableBodyProps,
        headerGroups,
        rows,
        prepareRow
    } = useTable({ columns, data: tableData });

基于 @gdh@canovice 的对话,你们都可以 table 更新状态更改并使用 useMemo

在上面的第 2 步中,只需将 tableData 添加到空数组中,其余所有代码都可以正常工作,您可以继续使用 useMemo

    // 2. Create Data - note `tableData` in the useMemo array
    const data = React.useMemo(() => tableData, [tableData]);

在这个例子中,我们说:

React, please memoize tableData (because it could be very costly to render) and rerender it ONLY when tableData changes.

这里发生的事情与 @gdh 解释的非常相似:需要通知 useMemo 挂钩来监视更新。放入数组的值是值 useMemo 监视以了解何时重新渲染。您还可以在该观察器数组中包含多个值(这就是为什么它是一个数组),因此它会在任何值更改时更新。

useMemo 参考文档:https://reactjs.org/docs/hooks-reference.html#usememo