早上好,我正在开发一个React应用程序,通过REST API与后端通信。
该应用程序体系结构还使用 React 路由器,并使用服务器提供并存储在会话存储
中的 JWT 令牌实现身份验证功能。
基本上:
/entsorga/home
的主页,其中应该显示带有路径/entsorga
的组件和带有路径/entsorga/home
的组件(如果一个很好地理解React路由器的工作)在启动应用程序时,用户被正确重定向到登录页面,并可以正确进行身份验证,身份验证后,页面url以正确的方式更改,但组件不会呈现,并显示后续错误。
虽然我对React完全陌生,但我面临着错误:
Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
我知道错误来自一个函数连续调用setState
的事实,我已经试图逐个消除对函数的调用,但这并不能解决问题,所以它不应该是关于我的一个函数。
React Router中是否有我可能错过的东西,它与组件生命周期钩子进行交互并使此错误发生?
指数tsx页面:
ReactDOM.render(
<React.StrictMode>
<BrowserRouter>
<Route exact path='/'>
{authenticationService.isUserAuthenticated() ? <Redirect to='/entsorgafin' /> : <Login />}
</Route>
<Route path='/entsorgafin'>
{authenticationService.isUserAuthenticated() ? <Redirect to='/entsorga/home' /> : <Redirect to='/' />}
</Route>
<Switch>
<Route path='/entsorga' component={Header} />
<Route path='/entsorga/home' component={Homepage} />
</Switch>
</BrowserRouter>
</React.StrictMode>,
document.getElementById('root')
);
Header.tsx组件:
class Header
extends Component<any, any>
{
//costruttore
constructor(props: any)
{
//props management
super(props);
//state management
this.state = {
anniAttivita: [],
nomeProprietaGrafici: [],
loggedIn: authenticationService.isUserAuthenticated
}
//methods binding
this.getAnniAttivita = this.getAnniAttivita.bind(this);
this.setProprietaCruscotto = this.setProprietaCruscotto.bind(this);
this.logout = this.logout.bind(this);
}
//component lifecycle hook --> creation
componentDidMount()
{
this.getAnniAttivita();
this.setProprietaCruscotto();
}
//metodo per recuperare gli anni di attività dell'impianto
getAnniAttivita()
{
utilityService.recuperaAnniAttivita().then(
r =>
{
this.setState({anniAttivita: r.data})
}
);
}
//metodo per settare le proprietà disponibili all'interno del cruscotto
setProprietaCruscotto()
{
let proprietaGrafici = [
{
beName: "caloPesoGiorno",
feName: "Calo Peso Giornaliero"
},
{
beName: "caloPeso",
feName: "Calo Peso"
},
{
beName: "temperaturaMateriale",
feName: "Temperatura Materiale"
},
{
beName: "temperaturaReattore",
feName: "Temperatura Reattore"
},
{
beName: "rhInterna",
feName: "RH Interna"
},
{
beName: "deltaP",
feName: "Delta P"
},
{
beName: "tempoLatenza55",
feName: "Tempo Latenza 55"
},
{
beName: "ph",
feName: "PH"
},
{
beName: "rh",
feName: "RH"
},
{
beName: "germinazione",
feName: "Germinazione"
},
{
beName: "inerti_litoidi",
feName: "Inerti Litoidi"
},
{
beName: "plastiche_vetri_metalli",
feName: "Plastiche, Vetri, Metalli"
}
]
this.setState({nomeProprietaGrafici: proprietaGrafici});
}
//effettua il logout
logout()
{
authenticationService.logout();
this.setState({loggedIn: false});
}
//metodo che effettua il render del componente
render()
{
if (this.state.loggedIn)
{
return (
<Redirect to='/' />
);
}
return (
<nav className="navbar navbar-light sticky-top navbar-expand-xl py-0 pl-0">
<Link className="navbar-brand py-0" to={"/entsorgafin/home"}>
<img src={logo} className="img-fluid d-inline-block align-top" alt="EntsorgaFin logo" />
</Link>
<button className="navbar-toggler" type="button" data-toggle="collapse"
data-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span className="navbar-toggler-icon" />
</button>
<div className="collapse navbar-collapse" id="navbarSupportedContent">
<ul className="navbar-nav mr-auto">
<li className="nav-item dropdown with-right-border">
<Link className="nav-link dropdown-toggle text-dark" to="#"
id="tracciabilitaLottiNavbarDropdown"
role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
DOCUMENTO TRACCIABILITÁ LOTTI
</Link>
<div className="dropdown-menu" aria-labelledby="tracciabilitaLottiNavbarDropdown">
{
//creazione di un link per ogni anno di attività
this.state.anniAttivita.map(
(anno: number) =>
{
return (
<Fragment>
<Link key={anno} className="dropdown-item text-center"
to={"/entsorgafin/tracciabilitaLotti"}>{anno}</Link>
<div className="dropdown-divider custom-dropdown-divider" />
</Fragment>
);
}
)
}
</div>
</li>
<li className="nav-item dropdown with-right-border">
<Link className="nav-link dropdown-toggle text-dark" to="#"
id="performanceImpiantoNavbarDropdown" role="button" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false">
PERFORMANCE D'IMPIANTO
</Link>
<div className="dropdown-menu" aria-labelledby="performanceImpiantoNavbarDropdown">
{
//creazione di un link per ogni anno di attività
this.state.anniAttivita.map(
(anno: number) =>
{
return (
<Fragment>
<Link key={anno} className="dropdown-item text-center"
to={"/entsorgafin/performanceImpianto"}>{anno}</Link>
<div className="dropdown-divider custom-dropdown-divider" />
</Fragment>
);
}
)
}
</div>
</li>
<li className="nav-item dropdown">
<Link className="nav-link dropdown-toggle text-dark" to="#"
id="cruscottoCompletoNavbarDropdown"
role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
CRUSCOTTO COMPLETO
</Link>
<div className="dropdown-menu" aria-labelledby="cruscottoCompletoNavbarDropdown">
{
//creazione di un link per ogni nome di proprietà disponibile
this.state.nomeProprietaGrafici.map(
(beName: string,
feName: string) =>
{
return (
<Fragment>
<Link key={beName}
className="dropdown-item text-center"
to={"/entsorgafin/performanceImpianto"}>${feName}</Link>
<div className="dropdown-divider" />
</Fragment>
);
}
)
}
</div>
</li>
</ul>
{/*<ul className="nav navbar-nav float-right-element">*/}
{/*<li>*/}
{/* /!*<h6 className="no-margin vertical-align-text mr-1">Utente attivo:*!/*/}
{/* /!* ${authenticationService.getCurrentUserName()} </h6>*!/*/}
{/*</li>*/}
{/*<li>*/}
{/*<button className="btn btn-sm btn-dark" onChange={this.logout}>Logout</button>*/}
{/*</li>*/}
{/*</ul>*/}
</div>
</nav>
);
}
}
export default Header;
Login.tsx组件:
class Login
extends Component<any, any>
{
//costruttore
constructor(props: any)
{
//props management
super(props);
//state management
this.state = {
username: '',
password: '',
loggedIn: authenticationService.isUserAuthenticated()
}
//methods binding
this.handleLogin = this.handleLogin.bind(this);
this.onChangeUserName = this.onChangeUserName.bind(this);
this.onChangePassword = this.onChangePassword.bind(this);
}
onChangeUserName(e: any)
{
this.setState({
username: e.target.value
});
}
onChangePassword(e: any)
{
this.setState({
password: e.target.value
});
}
handleLogin(e: any)
{
e.preventDefault();
authenticationService.authenticate(this.state.username, this.state.password).then(
() =>
{
this.setState({loggedIn: true});
}
);
}
render()
{
if (this.state.loggedIn)
{
return (
<Redirect push to='/entsorga/home' />
);
}
return (
<div className="col-md-12">
<div className="card">
Carta
</div>
<form onSubmit={this.handleLogin}>
<div className="form-group">
<label htmlFor="username">Nome Utente</label>
<input type="text" className="form-control" name="username" value={this.state.username}
onChange={this.onChangeUserName} required={true} />
</div>
<div className="form-group">
<label htmlFor="password">Password</label>
<input type="password" className="form-control" name="password" value={this.state.password}
onChange={this.onChangePassword} required={true} />
</div>
<div className="form-group">
<button className="btn btn-primary btn-block" type="submit" value="submit">
Login
</button>
</div>
</form>
</div>
);
}
}
export default Login;
主页仅打印带有H1标题的“主页”。
编辑
我编辑了索引。tsx类:
<Switch>
<Route exact path='/'>
{authenticationService.isUserAuthenticated() ? <Redirect to='/entsorga/home' /> : <Login />}
</Route>
<Route path='/entsorga' component={Header} />
<Route path='/entsorga/home' component={Homepage} />
<Route path='/entsorga/tracciabilitaLotti' component={tracciabilitaLotti} />
<Route path='/entsorga/performanceImpianto' component={performanceImpianto} />
<Route path='/entsorga/graficiCruscotto' component={graficiCruscotto} />
</Switch>
但是问题并没有解决,重定向的地方是:
>
在 index.tsx 文件中,如果用户未登录,则将其重定向到主页或以其他方式重定向到主页
<Route exact path='/'>
{authenticationService.isUserAuthenticated() ? <Redirect to='/entsorga/home' /> : <Login />}
</Route>
在登录成功时重定向到主页的login.tsx文件中:
if(this . state . logged in){ return(Redirect push to = '/ents orga/home ');}
header.tsx 文件,在用户未登录的情况下重定向到 / (以防止在用户未登录的情况下看到该页面)
if(this.state.loggedIn){return(重定向到='/');}
< code>loggedIn状态由调用服务的helper函数在组件的构造函数中给出,我确信身份验证是成功的,因为我可以在日志中打印身份验证令牌。
Header.tsx组件应该在所有页面上都被取消支付,这就是为什么我把它放在路径/entsorga中,所有其他组件都在/entsorga/**。
编辑2
在服务器日志中,我可以看到来自React的多个请求(比需要的请求多得多),就好像Header.tsx组件在不断地重新呈现一样:我看到一个组件在其状态被修改时自动重新呈现,在Header组件中,状态在构造函数中被修改,并且在执行注销(尚未使用)时,setProprietaCruscotto(仅使用过一次)和getAnniAttivita,这可能是不断重新加载的原因。
getAnniAttivita函数通过Axios调用API从服务器获取一些数据,服务器响应401(目前应该是这样),Axios可能是持续重新加载的原因吗?也许在错误之后,Axios会重试,直到调用成功,使状态多次改变?
<Route exact path='/'>
{authenticationService.isUserAuthenticated() ? <Redirect to='/entsorgafin' /> : <Login />}
</Route>
<Route path='/entsorgafin'>
{authenticationService.isUserAuthenticated() ? <Redirect to='/entsorga/home' /> : <Redirect to='/' />}
</Route>
这两条路由总是被渲染,因为它们没有被包装在交换机中。
现在,您在两条路由中都有重定向,并且在isUserAuthenticated
结果的相反一侧。
现在发生的是,你的应用程序在循环中被重定向,因为如果用户登录,将调用来自< code>entsorgafin的重定向,或者来自< code>/路径的重定向。
您需要将这些添加到开关中,现在只会呈现第一页。
我有这个错误:错误:超过最大更新深度。当组件重复调用componentWillUpdate或componentDidUpdate内部的setState时,会发生这种情况。React限制嵌套更新的数量,以防止无限循环。 但是我不明白怎么解决!我只是在发布我的代码,对不起… 我的代码:
我试图在参数更改时映射我的 redux 数组。它按预期呈现,但我在控制台中收到此错误。尝试了一些对useeffect的依赖性,但无法修复它。不知道为什么会发生这种情况。感谢您的帮助。 错误; 超过最大更新深度。当组件在useEffect中调用setState时,可能会发生这种情况,但useEfect要么没有依赖项数组,要么在每次渲染时都会更改其中一个依赖项。 我的代码;
我正在用React做我的前几个实验,在这个组件中,我调用了一个外部API来获取所有NBA玩家的列表,通过作为组件道具接收的teamId过滤它们,最后呈现过滤玩家的标记。 一个需要考虑的问题是,由于我调用了API并获得了一个大列表,所以我将它保持在组件的状态,以便对该组件的新调用将使用该状态,而不是再次调用API。这不是生产代码,我没有API,所以我这样做是因为我收到了“太多请求”消息,因为我一直在
我目前收到Maxiumum更新深度错误,不知道为什么。在我的代码中看不到无限循环。 "超过了最大更新深度。当组件在useEffect内部调用setState时,可能会发生这种情况,但useEffect要么没有依赖关系数组,要么其中一个依赖关系在每次渲染时都会发生变化。 此处显示错误 ReactJS组件代码: 下面的代码似乎有错误:超过了最大更新深度。当组件在useEffect中调用setState
我正在尝试使用master中的一些函数。js组件。当我运行下面的代码时,我得到错误“error:Maximum update depth exceeded。当组件在componentWillUpdate或componentDidUpdate.React中重复调用setState时,可能会发生这种情况。React限制嵌套更新的数量,以防出现无限循环。” 我在孙子组件中添加按钮时出错了。 如果我注释掉
当我运行我的代码时,我收到了这个错误。 超过了最大更新深度。当组件重复调用组件WillUpdate或组件DidUpdate中的setState时,可能会发生这种情况。React限制嵌套更新的数量以防止无限循环。 这是代码。它在引用。 我按照React网站上的文章所说的方式设置了我的东西,它“来了”于这个简洁的控制台类型,这就是我产生上述代码的地方。我对React、JSX和Javascript(以及