首页 > 解决方案 > 除非刷新页面,否则带有 React-Table 的 UseEffect 不会显示更改

问题描述

我是一名尝试学习 React 的 Java 开发人员,我遇到了这个问题,我更新了一个表以使用react-table,现在,每当我从我的 api 响应中添加或删除一个项目时,我都需要刷新整个页面才能看到发生了变化,而在我让我的 useEffect 立即显示这些变化之前。

在删除几乎所有其他试图找到此问题的根本原因之后,我在下面有我的完整代码。如果我使用注释掉的 tbody 而不是使用 react-table 的那个,我仍然可以看到我的更新工作正常且符合预期。

值得一提的是,如果我尝试setData在 useEffect 片段内部使用,反应表甚至不会被填充。

const {useTable} = require('react-table')

const MainTable = ({dataTableObj}) => {

const [reports, setReports] = useState(dataTableObj.reports)

const getInitialData = () => reports.map(report => ({
    name: report.title,
    runDate: report.runDate,
    createdDate: report.createdDate,
    category: report.category.title,
    actions: report.id,
}));

const [data, setData] = useState(getInitialData)

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

useEffect(() => {

    setReports(dataTableObj.reports)
    // setData(dataTableObj.reports)

}, [dataTableObj.reports]);

const onConfirmDelete = (id) => {

    deleteReport(id).then(() => {

        const del = reports.filter(report => id !== report.id)
        setReports(del)

    })
}

return (
    <div>
        <table {...getTableProps()}>
            <tbody {...getTableBodyProps()}>
            {rows.map((row, i) => {
                prepareRow(row)
                return (
                    <tr {...row.getRowProps()}>
                        <td>{row.original.name}</td>
                        <td>
                            <IconButton onClick={() => onConfirmDelete(row.original.actions)}>
                                <Delete/>
                            </IconButton>
                        </td>
                    </tr>
                )
            })}
            </tbody>
            {/*<tbody>*/}
            {/*{reports.map((item) => {*/}
            {/*    return [*/}
            {/*        <tr key={item.id}>*/}
            {/*            <td>{item.title}</td>*/}
            {/*            <td>*/}
            {/*                <IconButton onClick={() => onConfirmDelete(item.id)}>*/}
            {/*                    <Delete/>*/}
            {/*                </IconButton>*/}
            {/*            </td>*/}
            {/*        </tr>*/}
            {/*    ];*/}
            {/*})}*/}
            {/*</tbody>*/}
        </table>
    </div>
    )
}

export default MainTable

我想我现在已经没有什么想法了,我可能会错过什么,可能需要一些帮助或指导。

非常感谢。

标签: reactjsuse-effectreact-tablereact-table-v7

解决方案


我做了这个代码框来测试:https ://codesandbox.io/s/confident-drake-e47wm?file=/src/MainTable.js

如果您在 中切换第 9 行和第 10 行MainTable.js,您将切换它的工作和不工作。似乎当您将数据放入本地状态时(因为您正在映射它),它不会重新渲染。不完全确定这是为什么,我从来没有使用过 react-table,也许它在某个地方的文档中。

所以我认为你要么需要:

  1. 在父级中进行映射并将数据传递给MainTable已经映射的数据,或者
  2. 包装MainTable在另一个执行映射的组件中,然后再次将数据传递到MainTable已映射的
  3. 也许可以使用自定义钩子来完成,我没有尝试过。

推荐阅读