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

React-Query数据存入useState触发无限重渲染的原因与解决

错误原因与解决方法

错误原因

你在组件的顶层渲染逻辑中直接调用setUserLists,触发了无限重渲染循环:

  • 组件首次渲染时,若lists.isLoading为false,执行setUserLists更新状态
  • 状态更新会强制组件重新渲染
  • 重新渲染后再次进入判断逻辑,再次调用setUserLists,循环往复
  • React检测到这种无限循环,抛出Too many re-renders错误终止程序

正确实现方式

方式一:直接使用useQuery返回的数据(推荐)

useQuery本身会自动管理数据的加载、更新和缓存,完全不需要额外的useState来存储数据,直接用返回的lists.data.lists做条件渲染即可:

const lists = useQuery(["lists"], api.fetchLists);

if (lists.isLoading) {
  return <div>加载中...</div>;
}

// 根据lists.data.lists是否为空做条件渲染
return (
  <div>
    {lists.data.lists.length === 0 ? (
      <p>暂无数据</p>
    ) : (
      <ul>
        {lists.data.lists.map(item => (
          <li key={item.id}>{item.name}</li>
        ))}
      </ul>
    )}
  </div>
);

方式二:用useEffect监听数据变化存入useState

如果确实需要将数据存入本地state(比如要对数据做独立于接口的本地修改),可以通过useEffect监听lists.data的变化,仅当数据更新时才执行状态赋值:

import { useState, useEffect } from 'react';
import { useQuery } from '@tanstack/react-query';

const [userLists, setUserLists] = useState([]);
const lists = useQuery(["lists"], api.fetchLists);

useEffect(() => {
  // 仅当lists.data存在时更新本地state
  if (lists.data) {
    setUserLists(lists.data.lists);
  }
}, [lists.data]); // 依赖项设为lists.data,仅当数据变化时触发

if (lists.isLoading) {
  return <div>加载中...</div>;
}

return (
  <div>
    {userLists.length === 0 ? (
      <p>暂无数据</p>
    ) : (
      <ul>
        {userLists.map(item => (
          <li key={item.id}>{item.name}</li>
        ))}
      </ul>
    )}
  </div>
);

内容的提问来源于stack exchange,提问作者Daniel L

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 23:24:48