ReactJs抛出最大更新深度错误
Posted
技术标签:
【中文标题】ReactJs抛出最大更新深度错误【英文标题】:ReactJs throwing maximum update depth error 【发布时间】:2020-07-17 10:04:56 【问题描述】:我正在构建一个 React 应用来学习 React。我已经实现了上下文以在用户登录时存储有关用户的信息,并且还在本地存储中制作副本。我在 App 组件中验证用户是这样登录的
function App()
const [user, setUser] = useContext(UserContext);
return (
<div className="App">
<Router>
<NavBar />
<Switch>
<Route path="/login" exact>
!user.loggedIn ? <LoginForm /> : <Redirect to="/profile" />
</Route>
</Switch>
</Router>
</div>
);
而且这工作得很好。但是如果令牌已经过期;我希望用户被强制进入登录页面。这意味着我需要检查每个路由请求的过期时间,因为用户可以在其中的配置文件中,如果他们点击另一个链接,他们将被重定向到登录组件。我应该如何处理这个? 我试图在应用程序组件中使用 useEffect ,当它满足条件时将状态loggedIn设置为true,并进行比较
useEffect(function ()
const ct = parseInt(Date.now().toString(), 10);
const iat = parseInt(localStorage.getItem('iat'), 10);
if (ct - iat < 60000)
setUser( loggedIn: true );
else
setUser( loggedIn: false );
);
据我了解,每次渲染 App 组件时都会发生这种情况,因此我没有向 useEffect 提供任何输入,但这显然会引发 maximum update depth reached
错误。
我应该如何实现这种行为?
【问题讨论】:
【参考方案1】:编辑:
应用组件不会重新渲染,因为它永远不会改变,只有子组件会改变。您可以做的是,您可以将history.location
作为您的依赖项放在useEffect 中,每当路径更改时都会触发useEffect。见:How to listen to route changes in react router v4?
如果您在组件主体中使用 console.log,您会看到它会随着每个节点的更新而重新渲染很多次。您需要添加一个空的依赖数组或一些依赖项,以便它仅在需要时运行 useEffect。
useEffect(() =>
//your logic here
, [])
我认为您还可以通过再次检查您的 setUser
方法来缓解此错误。通过这种方式,您将减少对 setState 方法的大量不必要调用,这也是造成 maximum depth reached error
useEffect(function ()
//other code
if (!loggedIn && ct - iat < 60000)
setUser( loggedIn: true );
else if(loggedIn)
setUser( loggedIn: false );
);
此外,通常有更好的方法来检查用户是否需要重新验证,如果您使用的是 Axios,您可以在拦截器中设置检查以在拨打电话之前进行此比较,如果用户未经验证,则重定向他们登录页面。
【讨论】:
每次执行路由操作时都需要使用效果。我不确定如何将其添加为依赖项。对于第二种解决方案;我以前尝试过,但没有奏效。对于 axios;我还没有使用它,因为我只是在尝试学习 react 的基础知识。react-router
中是否有一个focused
参数可以用来在每次执行路由操作时触发useEffect,因为组件会发生变化。除此之外,带有空数组依赖数组的 useEffect 仍应在每次组件因路由更改而挂载和卸载时触发
如果你真的想这样做,那么考虑将 Private 和 Public 路由分开,并在 Private 路由被命中时检查身份验证。 reacttraining.com/react-router/web/example/auth-workflow 重申一下,我以前使用 useEffect 和一个空数组依赖项来执行此操作,它之所以有效,是因为每次安装和卸载组件时都会调用它。当你已经在没有 redux 或 axios 的路线上时,不确定你会怎么做
好的,现在我明白了一点。你是对的,应用程序组件不会重新渲染,因为它永远不会改变,只有子组件是。您可以做的是,您可以将history.location
作为您的依赖项放在useEffect 中,每当路径更改时都会触发useEffect。见:***.com/questions/41911309/…
很高兴它解决了您的问题。我会更新答案,以便将来任何人也可以轻松解决。【参考方案2】:
使用“react-router-dom”中的 useLocation。然后let location = useLocation()
和useEffect(function()//do stuff, [location])
。这样,我们将在 url 发生变化时运行 useEffect。
【讨论】:
以上是关于ReactJs抛出最大更新深度错误的主要内容,如果未能解决你的问题,请参考以下文章