React TanStack Table渲染报错:数据未加载时触发length读取异常
TanStack React-Table 加载数据前渲染导致「Cannot read properties of undefined (reading 'length')」错误解决
问题描述
使用TanStack react-table时,表格在数据加载完成前提前渲染,触发Cannot read properties of undefined (reading 'length')错误,错误指向table.getRowModel().rows.map代码行。已尝试设置默认空数组、使用useMemo等方案未解决,怀疑useEffect使用方式存在问题。客户端渲染模式下,父组件与DataTable组件简化代码如下:
父组件代码
'use client' import React, { useEffect, useState } from 'react' import DataTable from '../components/DataTable' import axios from 'axios'; export default function MainPage() { const [data, setData] = useState([]) useEffect(() => { const data = getReports(); setData(data); }, []) const columns = [ { id: 1, label: 'user ID', accessorKey: 'userID' }, { id: 2, label: 'id', assecorKey: 'id' }, { id: 3, label: 'body', accesorKey: 'body' }, { id: 4, label: 'title', assecorKey: 'title' }, ] return ( <div> <h1>Reports</h1> <DataTable data={data} columns={columns}/> </div> ) }
DataTable组件代码
import React from "react"; import { useReactTable, getCoreRowModel, flexRender, } from "@tanstack/react-table"; export default function DataTable({ data, columns }) { const table = useReactTable({ data, columns, getCoreRowModel: getCoreRowModel(), }); return ( <div> <div className="border-solid border-2 rounded mt-5"> <table> {table.getHeaderGroups().map((headerGroup) => ( <tr key={headerGroup.id}> {headerGroup.headers.map((header) => ( <th key={header.id}> {flexRender( header.column.columnDef.label, header.getContext() )} </th> ))} </tr> ))} <tbody> {table.getRowModel().rows.map(row => ( <tr key={row.id}> {row.getVisibleCells().map(cell => ( <td key={cell.id}> {flexRender(cell.column.columnDef.cell, cell.getContext())} </td> ))} </tr> ))} <tr> <td>id</td> </tr> </tbody> </table> </div> </div> ); }
错误原因分析
- 异步请求处理错误:
getReports()是异步函数,直接赋值给data会得到Promise对象而非实际数据,导致传给DataTable的data为Promise,react-table无法正常解析。 - 列定义拼写错误:多个列的
accessorKey字段拼写错误(写成assecorKey/accesorKey),react-table无法识别列字段,引发内部数据处理异常。 - 组件props无兜底处理:未给DataTable的
data和columns设置默认值,若传入非预期值会导致表格渲染失败。
解决方案
1. 修复异步请求逻辑
父组件中正确处理异步函数,使用async/await获取数据:
'use client' import React, { useEffect, useState } from 'react' import DataTable from '../components/DataTable' import axios from 'axios'; export default function MainPage() { const [data, setData] = useState([]) // 定义异步数据请求函数 const getReports = async () => { try { const res = await axios.get('你的数据接口地址'); return res.data; } catch (err) { console.error('数据加载失败:', err); return []; } }; useEffect(() => { // 正确执行异步请求并更新state const fetchData = async () => { const result = await getReports(); setData(result); }; fetchData(); }, []) // 修复列定义的拼写错误 const columns = [ { id: 1, label: 'user ID', accessorKey: 'userID' }, { id: 2, label: 'id', accessorKey: 'id' }, { id: 3, label: 'body', accessorKey: 'body' }, { id: 4, label: 'title', accessorKey: 'title' }, ] return ( <div> <h1>Reports</h1> <DataTable data={data} columns={columns}/> </div> ) }
2. 增强DataTable组件健壮性
给props设置默认值,增加空数据兜底渲染:
import React from "react"; import { useReactTable, getCoreRowModel, flexRender, } from "@tanstack/react-table"; export default function DataTable({ data = [], columns = [] }) { // 确保传入的data和columns为有效数组 const table = useReactTable({ data: Array.isArray(data) ? data : [], columns: Array.isArray(columns) ? columns : [], getCoreRowModel: getCoreRowModel(), }); return ( <div> <div className="border-solid border-2 rounded mt-5"> <table> <thead> {table.getHeaderGroups().map((headerGroup) => ( <tr key={headerGroup.id}> {headerGroup.headers.map((header) => ( <th key={header.id}> {flexRender( header.column.columnDef.label, header.getContext() )} </th> ))} </tr> ))} </thead> <tbody> {/* 空数据/加载中状态提示 */} {table.getRowModel().rows.length === 0 ? ( <tr> <td colSpan={columns.length} className="text-center py-4"> 加载中...暂无数据 </td> </tr> ) : ( table.getRowModel().rows.map(row => ( <tr key={row.id}> {row.getVisibleCells().map(cell => ( <td key={cell.id}> {/* 兜底处理cell渲染逻辑 */} {flexRender(cell.column.columnDef.cell || cell.getValue(), cell.getContext())} </td> ))} </tr> )) )} </tbody> </table> </div> </div> ); }
3. 关键修复点总结
- 异步函数必须通过
async/await或.then()获取结果,不能直接将Promise赋值给state - 严格检查列定义的字段拼写,确保
accessorKey正确无误 - 给组件props设置默认值,避免非预期值导致的渲染错误
内容的提问来源于stack exchange,提问作者ams
相关产品推荐
相关产品推荐

