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
相关产品推荐
相关产品推荐

