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

React中setCourseList触发无限重渲染的问题求助

问题分析与解决方案

无限重渲染的核心原因

你遇到的无限循环不是事件处理器里的setCourseList导致的,问题出在:

  • 你把页面初始化的axios.post('http://localhost:8000/api/course', data)直接写在组件函数的顶层代码中。React组件每次渲染(比如调用任何setState方法后)都会重新执行整个函数体,这就导致这个axios请求会被反复触发,请求完成后调用setCourseList又会触发组件重新渲染,形成无限循环。

修复步骤

1. 用useEffect限制初始请求的执行时机

把页面加载时的axios请求放到useEffect钩子中,设置空依赖数组,确保它只在组件挂载时执行一次:

import React, { useState, useEffect } from 'react'; // 新增useEffect导入
// ...其他导入代码

// 把Cookies实例移到组件外,避免每次渲染重复创建
const cookies = new Cookies();

function Course() {
    // ...其他状态定义
    
    const [courseList, setCourseList] = useState([]);
    
    // 初始数据请求:仅在组件首次挂载时执行
    useEffect(() => {
        axios
        .post('http://localhost:8000/api/course', { email: cookies.get('email') })
        .then((res) => {
            setLoading(false);
            setCourseList(res.data.course);
            console.log(res.data.course);
        })
        .catch(err => {
          console.error(err);
          setLoading(false); // 出错也要关闭加载状态,避免页面一直卡住
        });
    }, []); // 空依赖数组,确保只执行一次

    // ...其他函数定义
}

2. 阻止表单默认提交行为

你的handleClick是表单onSubmit的回调,默认会触发页面刷新,必须添加e.preventDefault()阻止这个默认行为:

function handleClick(e) {
    e.preventDefault(); // 阻止表单默认提交,避免页面刷新
    setShowResults(false);
    setLoading(true);
    
    axios
    .post('http://localhost:8000/api/add-course', data)
    .then((res) => {
        setCourseList(res.data.course);
        setLoading(false); // 请求完成后关闭加载状态
        console.log(res);
    })
    .catch(err => {
      console.error(err);
      setLoading(false); // 出错也要关闭加载状态
    });
}

3. 额外优化点

  • 移除组件中多余的<body>标签:React组件只负责页面局部内容的渲染,<body>是根层级标签,应该由React入口文件管理。
  • 简化handleInput的写法:
function handleInput(e) {
    const { id, value } = e.target;
    setData(prev => ({ ...prev, [id]: value }));
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 14:20:26