【问题标题】:ReactJs throwing maximum update depth errorReactJs抛出最大更新深度错误
【发布时间】: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 错误。 我应该如何实现这种行为?

【问题讨论】:

    标签: node.js reactjs session jwt


    【解决方案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。见:stackoverflow.com/questions/41911309/…
    • 很高兴它解决了您的问题。我会更新答案,以便将来任何人也可以轻松解决。
    【解决方案2】:

    使用“react-router-dom”中的 useLocation。然后let location = useLocation()useEffect(function(){//do stuff}, [location])。这样,我们将在 url 发生变化时运行 useEffect。

    【讨论】:

      猜你喜欢
      • 2020-07-15
      • 1970-01-01
      • 2019-10-23
      • 2019-11-21
      • 1970-01-01
      • 2020-01-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多