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

使用TanStack Table与Query时的重复渲染及冗余API调用问题

问题修复方案

核心问题分析

  1. 日期筛选后页码未重置:设置日期时未强制将pageIndex设为0,导致请求旧页码数据,可能返回空结果;后续表格组件可能因总页数更新自动调整页码,触发多余请求。
  2. 日期选择器开关触发冗余请求:日期选择器的弹窗状态变化可能引发父组件不必要重渲染,或事件处理逻辑意外触发了状态更新。
  3. 分页状态不同步:表格组件的分页回调可能在数据更新后被意外触发,导致pageIndex被重置回旧值。

具体修复步骤

1. 修复日期筛选时的页码重置逻辑

补全handleDateChange函数,确保选择日期时强制回到第一页:

const handleDateChange = (date: Date | null) => {
  setSelectedDate(date);
  // 筛选条件变更,强制重置页码为0
  setPageIndex(0);
};

2. 避免日期选择器开关触发冗余请求

确保弹窗状态isDatePickerOpen不影响查询依赖,同时简化日期选择器的事件处理:

<DatePicker
  selected={selectedDate}
  onChange={handleDateChange}
  placeholderText="Filter by: Date"
  className="border text-[14px] border-[#D9D9D9] rounded-t-[15px] rounded-b-none px-4 py-1.5 rounded"
  open={isDatePickerOpen}
  onCalendarOpen={() => setIsDatePickerOpen(true)}
  onCalendarClose={() => setIsDatePickerOpen(false)}
  customInput={<CustomInput />}
  popperClassName="left-0 right-0 md:!-left-[30px]"
/>

若isDatePickerOpen仅用于控制弹窗,可考虑将其改为日期选择器内部状态(如组件支持),避免提升到父组件引发不必要重渲染。

3. 修复数据请求的闭包问题

当前fetchPackageDetails直接引用组件状态selectedDate,存在闭包风险,修改为使用传入参数:

const fetchPackageDetails = async (params: { startDate?: string; endDate?: string } & FetchParams) => {
  try {
    const response = await getPaginatedPackageDetails(params);
    if (response.status === 200 || response.status === 204) {
      return response;
    }
  } catch (error) {
    console.log('Error while fetching package details: ', error);
  }
};

// 在useQuery的查询函数中处理日期转换
queryFn: async () => {
  let params: FetchParams & { startDate?: string; endDate?: string } = {
    pageSize,
    pageIndex,
    searchQuery,
    sortField: sorting[0]?.id || '',
    sortOrder: sorting[0]?.desc ? 'desc' : 'asc',
  };
  if (selectedDate) {
    const { start, end } = convertToUTCStartAndEnd(selectedDate);
    params.startDate = start;
    params.endDate = end;
  }
  if (activeTab === 'package') {
    return await fetchPackageDetails(params);
  }
  // 其他标签页逻辑
}

4. 禁用表格自动重置页码

在ServerDataTable内部的表格配置中,禁用自动重置页码功能,确保筛选变更时页码由手动控制:

// ServerDataTable组件内部的useTable配置
const table = useTable({
  columns,
  data,
  pageCount,
  initialState: { pageIndex: 0, pageSize: 5 },
  autoResetPageIndex: false, // 关闭自动重置页码
  onPaginationChange: onPaginationChange,
  // 其他配置项
});

5. 优化查询键(queryKey)

确保查询键包含所有影响请求的参数,同时避免引用不稳定对象:

queryKey: [
  'bookingList',
  activeTab,
  pageSize,
  pageIndex,
  searchQuery,
  JSON.stringify(sorting), // 将排序数组转为字符串,避免引用变化触发冗余请求
  selectedDate ? selectedDate.toISOString() : null, // 将日期转为字符串,确保状态变化被正确识别
],

验证修复效果

  1. 选择日期后,确认pageIndex被设为0,且仅触发一次API请求
  2. 打开/关闭日期选择器时,无冗余API请求
  3. 日期筛选后表格显示正确数据,无空页面或错误页码情况

内容的提问来源于stack exchange,提问作者Dev Pathak

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 11:43:13