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

如何解决React函数组件Too many re-renders无限重渲染错误?

解决React函数组件无限重渲染的问题

嘿,我一眼就揪出问题所在啦!你在组件的顶层直接写了setLoading(false);——这就是触发无限循环的罪魁祸首。

为什么会出现无限重渲染?

React函数组件每次渲染时,都会从头到尾执行整个函数体的代码。你把setLoading(false);直接放在函数顶层,意味着每次组件渲染都会调用这个状态更新函数,而状态更新又会触发组件重新渲染,这样就形成了「渲染→更新状态→再渲染→再更新状态」的死循环,React为了保护应用不崩溃,就抛出了「Too many re-renders」的错误。

修复步骤

那行单独的setLoading(false);本来应该是clearUsers函数的一部分,你不小心把它写到函数外面了。只需要把它移进clearUsers的函数体内就行:

原来的错误代码:

// Clear users from state
const clearUsers = () => setUsers([]);
setLoading(false);

修正后:

// Clear users from state
const clearUsers = () => {
  setUsers([]);
  setLoading(false);
};

修正后的完整代码

import React, {Fragment, useState} from 'react';
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import Navbar from './Components/Layout/Navbar';
import Users from './Components/users/Users';
import User from './Components/users/User';
import Search from './Components/users/Search';
import Alert from './Components/Layout/Alert';
import About from './Components/pages/About';
import './App.css';
import Axios from 'axios';

const App = () => {
 const [users, setUsers] = useState( [] );
 const [user, setUser] = useState( {} );
 const [repos, setRepos] = useState( [] );
 const [loading, setLoading] = useState( false );
 const [alert, setAlert] = useState( null );

 // Search Github Users
 const searchUsers = async text => {
 setLoading(true);
 const res = await Axios.get(`https://api.github.com/search/users?q=${text}&client_id=${process.env.REACT_APP_GITHUB_CLIENT_ID}&client_secret=${process.env.REACT_APP_GITHUB_CLIENT_SECRET}`);
 setUsers(res.data.items);
 setLoading(false);
 };

 // Get single github user
 const getUser = async username => {
 setLoading(true);
 const res = await Axios.get(`https://api.github.com/users/${username}?&client_id=${process.env.REACT_APP_GITHUB_CLIENT_ID}&client_secret=${process.env.REACT_APP_GITHUB_CLIENT_SECRET}`);
 setUser(res.data);
 setLoading(false);
 };

 // Get users repos
 const getUserRepos = async username => {
 setLoading(true);
 const res = await Axios.get(`https://api.github.com/users/${username}/repos?per_page=5&sort=created:asc&client_id=${process.env.REACT_APP_GITHUB_CLIENT_ID}&client_secret=${process.env.REACT_APP_GITHUB_CLIENT_SECRET}`);
 setRepos(res.data);
 setLoading(false);
 };

 // Clear users from state
 const clearUsers = () => {
  setUsers([]);
  setLoading(false);
 };

 // Set Alert
 const showAlert = (msg, type) => {
 setAlert({msg, type});
 setTimeout(()=> setAlert(null),3000);
 };

 return (
 <Router>
 <div className="App">
 <Navbar />
 <div className="container">
 <Alert alert={alert} />
 <Switch>
 <Route exact path='/' render={props => (
 <Fragment>
 <Search searchUsers={searchUsers} clearUsers={clearUsers} showClear={ users.length>0? true : false } setAlert={showAlert} />
 <Users loading={loading} users={users} />
 </Fragment>
 )} />
 <Route exact path = '/about' component={About} />
 <Route exact path= '/user/:login' render={props => (
 <User {...props} getUser={getUser} getUserRepos={getUserRepos} user={user} repos={repos} loading={loading} />
 )} />
 </Switch>
 </div>
 </div>
 </Router>
 );
}

export default App;

额外小提醒

以后写函数组件时要记住:状态更新函数(比如setXxx)不要直接放在组件顶层执行,除非你用useEffect加了合适的依赖项来控制执行时机。所有状态更新都应该放在事件处理函数、异步回调或者useEffect里面,这样才能避免不必要的重渲染。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 20:23:01