React函数组件使用axios获取API数据渲染下拉框死循环问题修复
React 函数组件Axios无限请求+Select下拉不渲染修复
问题根因
- 无限循环触发原因:直接在函数组件顶层执行
fetchData()调用,组件每次渲染都会发起请求;请求返回后调用状态更新方法触发重渲染,重渲染又再次执行fetchData(),形成「请求→更新状态→重渲染→再请求」的死循环。 - 下拉无数据原因:接口返回的分类数组存放在响应体的
data字段下(即response.data.data),原代码错误对整个响应对象做Object.entries转换,完全没有拿到实际的分类列表数据。 - 状态逻辑冲突:原代码把下拉选项列表和当前选中值都存在
selectedValue同一个状态中,而<select>标签的value属性需要绑定单个选中值,不能绑定整个数组,导致渲染逻辑异常。
修复方案
- 用
useEffect包裹接口请求逻辑,传入空依赖数组[],保证请求仅在组件首次挂载时执行1次,从根源避免重复请求。 - 拆分两个独立状态:一个存储所有下拉选项,一个存储当前选中的选项值,职责分离避免逻辑冲突。
- 修正数据处理逻辑,直接读取接口返回的分类数组,遍历生成下拉选项需要的
label、value字段,建议用接口返回的唯一_id作为选项value,避免分类重名导致的选中异常。
修复后完整代码
import { useState, useEffect } from 'react'; import axios from 'axios'; function CategorySelect() { // 选项列表状态 const [categoryOptions, setCategoryOptions] = useState([]); // 当前选中值状态 const [selectedCategory, setSelectedCategory] = useState(''); useEffect(() => { const fetchCategoryList = async () => { try { const res = await axios.get('http://localhost:5080/list-categories'); // 提取接口返回的分类数组 const list = res.data.data; // 转换为下拉需要的option格式 const options = list.map(item => ({ label: item.name, value: item._id })); setCategoryOptions(options); } catch (err) { console.error('获取分类列表失败:', err); } }; fetchCategoryList(); }, []); // 空依赖,仅组件挂载时执行 return ( <select value={selectedCategory} onChange={e => setSelectedCategory(e.target.value)} > <option value="" disabled>请选择分类</option> {categoryOptions.map(option => ( <option key={option.value} value={option.value}> {option.label} </option> ))} </select> ); } export default CategorySelect;
补充说明:如果后续需要根据其他查询参数重新拉取分类列表,只需要把对应的参数变量加入
useEffect的依赖数组即可,永远不要在函数组件的顶层直接执行数据请求、订阅这类带副作用的逻辑。
内容的提问来源于stack exchange,提问作者Nidhi Mahajan
相关产品推荐
相关产品推荐

