React动态表格开发重载时报Maximum update depth exceeded错误如何解决
问题原因
触发Maximum update depth exceeded错误的核心是columns变量没有做缓存:组件每次重渲染时都会生成一个全新的数组对象,useTable接收到新的columns参数后会重新计算表格实例,再次触发组件重渲染,最终陷入无限循环。
修复方案
将columns的生成逻辑也用useMemo缓存,依赖项和data保持一致即可,修改后的代码如下:
关键逻辑修改
const data = useMemo(() => MOCK_DATA, []); // 新增useMemo包裹columns生成逻辑 const columns = useMemo(() => { return Object.keys(data[1]).map((key, id) => { return { Header: key, accessor: key }; }); }, [data]);
完整组件代码
import { useMemo } from 'react'; import { useTable } from 'react-table'; export const DisplayTable = () => { const data = useMemo(() => MOCK_DATA, []); const columns = useMemo(() => { return Object.keys(data[1]).map((key, id) => { return { Header: key, accessor: key }; }); }, [data]); console.log(columns); const tableInstance = useTable({ columns, data }); const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } = tableInstance; 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()}> {rows.map((row) => { prepareRow(row); return ( <tr {...row.getRowProps()}> {row.cells.map((cell) => { return <td {...cell.getCellProps()}>{cell.render("Cell")}</td>; })} </tr> ); })} </tbody> </table> ); };
可选优化
如果你的MOCK_DATA是组件外部定义的静态常量,也可以直接把columns和data都提到组件外部定义,不需要用到useMemo即可避免重复生成对象:
// 组件外部定义静态数据 const data = MOCK_DATA; const columns = Object.keys(data[1]).map((key, id) => ({ Header: key, accessor: key })); export const DisplayTable = () => { const tableInstance = useTable({ columns, data }); // 剩余渲染逻辑和之前一致 }
内容的提问来源于stack exchange,提问作者Kevin Bryan Aban
相关产品推荐
相关产品推荐

