React页面递归渲染触发Too many re-renders错误问题排查
问题分析与修复方案
问题根源
- 你直接在组件函数体中执行
Fetchmovies().then(setMovies_list(movies_list)),每次组件渲染都会触发这段代码,而setMovies_list会引发组件重渲染,形成无限循环,导致出现「Too many re-renders」错误。 - 错误地直接修改状态变量
movies_list,React状态必须通过setMovies_list更新,不能直接赋值。 then(setMovies_list(movies_list))是立即执行状态更新,没有把回调函数传给then,而且此时movies_list还是初始的空数组,完全达不到更新目的。
修复步骤
- 使用
useEffect钩子,让API请求只在组件首次挂载时执行一次。 - 修正异步请求的写法,正确获取接口返回数据并更新状态。
- 移除直接修改状态变量的代码,严格遵循React状态更新规则。
修正后的完整代码
import React, { useState, useEffect } from 'react'; import Card from '@mui/material/Card'; import Divider from '@mui/material/Divider'; import CardContent from '@mui/material/CardContent'; import Autocomplete from '@mui/material/Autocomplete'; import TextField from '@mui/material/TextField'; function GetMovies() { const [movies_list, setMovies_list] = useState([]); useEffect(() => { async function fetchMovies() { try { const response = await fetch('你的API地址', { method: 'GET', headers: { 'Accept': 'application/json', 'authorization': '你的token' }, }); const data = await response.json(); setMovies_list(data); console.log(data); } catch (e) { console.error('请求电影列表失败:', e); } } fetchMovies(); }, []); // 空数组作为依赖,确保只执行一次 return ( <Card> <Divider /> <CardContent> <Autocomplete id='movies' name='movies' getOptionLabel={(option) => option.service_name} // 注意参数名不要和状态变量重名 multiple options={movies_list} renderInput={(params) => <TextField {...params} label='受影响的电影:' />} /> </CardContent> </Card> ); } export default GetMovies;
关键说明
useEffect的第二个参数传空数组[],告诉React这个副作用只在组件挂载时执行一次,避免重复调用API。- 异步函数内部通过
await正确获取响应和解析JSON,直接用setMovies_list(data)更新状态,不再直接修改movies_list。 - 把
getOptionLabel的参数名从movies_list改成option,避免和状态变量重名导致的逻辑混乱。
内容的提问来源于stack exchange,提问作者user971741
相关产品推荐
相关产品推荐

