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

React中useEffect内Fetch请求触发无限循环问题排查

React组件无限循环调用API问题修复

从你提供的API请求情况能看到,/allotherusers接口被持续重复调用,你的代码里有几个明显问题导致了这个无限循环,具体分析和修复方案如下:

问题根源

  1. useEffect执行时机失控:你的useEffect依赖数组里添加了setusers和setloading,但这两个是useState返回的 setter 函数,React会保证它们的引用在组件生命周期内稳定,不会触发useEffect重复执行。但你没有限制useEffect仅在组件挂载时执行,导致每次组件状态更新(比如调用setusers后),useEffect都会重新执行,进而再次调用API、更新状态,陷入循环。
  2. 组件命名冲突:组件名为Date,和JavaScript内置的Date构造函数重名,可能引发React渲染时的意外重复渲染问题。
  3. 错误的导航实现:在fetch回调里返回<Navigate to="/" />是错误用法,Navigate是React组件,需在JSX中渲染,或用useNavigate钩子实现编程式导航,这种写法不仅无效,还可能触发额外渲染。
  4. 缺少错误处理:fetch请求未处理网络或服务器错误,一旦请求失败,setloading(false)永远不会执行,页面会一直处于加载状态。

修复后的代码

import { useCookies } from "react-cookie";
import React, { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";

// 重命名组件,避免与内置Date冲突
const UserDate = () => {
    const [cookies] = useCookies(['XRSF-TOKEN']);
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState(false);
    const [users, setUsers] = useState([]);
    // 使用useNavigate实现编程式导航
    const navigate = useNavigate();

    useEffect(() => {
        const fetchUsers = async () => {
            setLoading(true);
            try {
                const response = await fetch("/allotherusers", { credentials: "include" });
                const body = await response.text();
                if (body === '') {
                    navigate("/");
                    return;
                }
                setUsers(JSON.parse(body));
            } catch (err) {
                setError(true);
                console.error('用户列表请求失败:', err);
            } finally {
                setLoading(false);
            }
        };

        fetchUsers();
    }, [navigate]); // 仅依赖navigate,它是稳定的引用

    const userList = users.map(user => {
        // 添加唯一key属性,符合React列表渲染规范
        return (
            <div key={user.id || user.firstname}>
                <p>{user.firstname}</p>
                <button onClick={() => like(user, false)}>Like</button>
            </div>
        );
    });

    const like = async (likedUser, superlike) => {
        const likeModel = {
            likedUser: likedUser,
            superlike: superlike
        };

        try {
            await fetch('/liked', {
                method: 'POST',
                headers: {
                    'X-XSRF-TOKEN': cookies['XRSF-TOKEN'],
                    'Accept': 'application/json',
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(likeModel),
                credentials: 'include'
            });
        } catch (err) {
            console.error('点赞请求失败:', err);
        }
    };

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

    if (error) {
        return <div>加载失败,请稍后重试</div>;
    }

    return (
        <div>
            {userList}
        </div>
    );
};

export default UserDate;

额外优化说明

  • 给map生成的列表项添加唯一key属性,避免React渲染警告和性能问题。
  • 将fetch改为async/await写法,代码逻辑更清晰易读。
  • 给点赞函数也添加错误处理,避免请求失败时控制台无提示。
  • 统一变量命名为小驼峰风格(如setloading改为setLoading),提升代码可读性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 05:50:24