首页 > 解决方案 > 当父级传递新数据或更新数据时重新渲染表格组件

问题描述

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

使用此处的示例指南,我正在我的 react 应用程序中设置一个初始表,尝试将表连接到我的应用程序的实时数据,该数据是使用 Axios 获取的。但是,我正在努力使用最初的重要功能 - 让 Table 组件显示/更新我传递给它的数据,但只有在数据更改之后

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

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 列的瘦表,然后获取一个具有 20 列的更大的表来替换父组件状态下的第一个表), UI 不会在我的网络应用程序上更新。(我认为是因为表格组件的内部状态没有更新?)

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

我正在使用它来计算钩子和无头组件,并希望遵循使用这个库的最佳实践,因为从 docs + 示例来看,它似乎是一个非常好的和强大的 React 表组件。

编辑

为了快速更新和澄清,父组件触发 2 个单独的异步 Axios 获取以更新相同的父状态变量可能是一种不好的模式。我不知道。正如我所提到的,只是为了澄清,第一次获取快速获取数据的精简版本,而第二次获取获取整个表。因为父状态使用新的数据数组进行更新,所以作为tableDataprop传递的数组<MyReactTable7Table />也会发生变化。

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

标签: javascriptreactjsreact-hooksreact-table

解决方案


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

在您的情况下,不需要 2nd useMemo

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

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

像这样:

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

推荐阅读