You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tanstack react-query与react-table:为何引发无限重渲染?

React Query与React Table联用导致无限重渲染的原因及解决方法

问题重现

以下代码会导致App组件无限重渲染,控制台持续输出component triggered:

import React from 'react'
import { QueryClient, QueryClientProvider, useQuery } from 'react-query'
import {
  useReactTable,
  createColumnHelper,
  getCoreRowModel
} from '@tanstack/react-table'

const queryClient = new QueryClient()
const columnHelper = createColumnHelper()

const columns = [
  columnHelper.accessor('thing', {
    header: 'thing',
    cell: () => ''
  })
]

const AppContextWrapper = () => {
  return (
    <QueryClientProvider client={queryClient}>
      <App />
    </QueryClientProvider>
  )
}

const App = () => {
  const query = useQuery(['test'], () => '')

  const table = useReactTable({
    data: [],
    columns,
    getCoreRowModel: getCoreRowModel()
  })
  console.log('component triggered')

  return table.getRowModel().rows.length
}

export default AppContextWrapper

原因分析

核心问题出在useReactTable的配置项getCoreRowModel: getCoreRowModel():

  • 每次App组件渲染时,getCoreRowModel()都会被调用,生成一个全新的函数实例。
  • useReactTable会对比配置项的引用变化,当getCoreRowModel的引用改变时,会重新计算表格实例,进而触发组件重渲染。
  • 组件重渲染又会再次调用getCoreRowModel()生成新实例,形成无限循环。

另外,useQuery的状态切换(从loading到success)会触发第一次重渲染,而上述循环逻辑会让重渲染持续下去。

解决方法

将getCoreRowModel()的结果缓存起来,避免每次渲染生成新实例:

方案1:将核心模型函数移到组件外部

因为getCoreRowModel()的结果是静态的,不需要依赖组件内部状态,可以直接在组件外定义:

// 移到组件外部,只初始化一次
const coreRowModel = getCoreRowModel()

const App = () => {
  const query = useQuery(['test'], () => '')

  const table = useReactTable({
    data: [],
    columns,
    getCoreRowModel: coreRowModel
  })
  console.log('component triggered')

  return table.getRowModel().rows.length
}

方案2:用useMemo包裹(适合依赖组件内部状态的场景)

如果getCoreRowModel需要依赖组件内的变量,可以用useMemo缓存:

const App = () => {
  const query = useQuery(['test'], () => '')

  const coreRowModel = React.useMemo(() => getCoreRowModel(), [])

  const table = useReactTable({
    data: [],
    columns,
    getCoreRowModel: coreRowModel
  })
  console.log('component triggered')

  return table.getRowModel().rows.length
}

额外注意事项

  • 确保useReactTable配置中的所有函数(如getCoreRowModel、getFilteredRowModel等)都不会在每次渲染时生成新实例。
  • 静态配置项(如columns)尽量放在组件外部,避免不必要的引用变化。

内容的提问来源于stack exchange,提问作者Andy Pandy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 09:08:31