导致无限循环的React Hook SetState

时间:2020-10-31 18:50:02

标签: reactjs react-hooks components infinite-loop setstate

下面是我的代码,我试图在注销按钮内调用setState,因为此按钮仅在Auth0 isLoggedIn为true时才呈现。 这似乎造成了无限循环,我猜是因为正在调用Auth0 API 每次。我正在学习本教程:https://www.youtube.com/watch?v=35lXWvCuM8o 唯一的区别是我试图在没有onClick函数的情况下调用setState, 谁能给我解释一下问题和解决方法,谢谢!

我了解我可以使用localStorage来维护用户登录会话,但是我这样做纯粹是为了学习React Hooks,

import React, { useState, useContext, useCallback} from 'react';
    import { useAuth0 } from '@auth0/auth0-react';
    import { ValueContext } from './ValueContext'

    const LogoutButton = () => {
 
    const [login, setLogin] = useContext(ValueContext);


  const { logout, isAuthenticated } = useAuth0();
  const updateLogin = () => {
    setLogin({loggedIn:'false'});
  };

  return (
    
    isAuthenticated && (
      <>
      <button onClick={() => logout()}>
        Log Out
      </button>
      
      <h1>{login.loggedIn}</h1>
     {updateLogin()}
   
          
         
       
      
    
      </>
      
    )

4 个答案:

答案 0 :(得分:0)

您要在渲染函数中调用updateLogin(),因此您要为每个渲染设置loggedIn: true。不要将函数或控制台日志直接放在return函数的内部,如果需要的话,不要将它们放在主LogoutButton函数体内。但是updateLogin()仅应在某些onPress内部调用。

答案 1 :(得分:0)

每次渲染组件时,都调用updateLogin()。这将设置状态variabel登录。这将导致组件再次呈现,并且过程不断循环。

答案 2 :(得分:0)

唯一的区别是我试图在没有onClick函数的情况下调用setState

差异很大! setState不应在渲染函数的主体中调用,或者至少有条件地调用它。否则,您将获得setState->渲染-> setState->渲染-> ...无休止。

您可以尝试以下方法:

    let alreadySet = false;

    const LogoutButton = () => {
    const [login, setLogin] = useContext(ValueContext);
    const { logout, isAuthenticated } = useAuth0();
    const updateLogin = () => {
      setLogin({loggedIn:'false'});
    };

    if(!alreadySet){
      alreadySet = true;
      updateLogin()
    }

    return ( 
    isAuthenticated && (
      <>
      <button onClick={() => logout()}>
        Log Out
      </button>   
      <h1>{login.loggedIn}</h1>
      </>
    )

请注意

    let alreadySet = false;
....
{
    if(!alreadySet){
      alreadySet = true;
      updateLogin()
    }
}

这意味着loginIn只会更新一次。是你想要的吗?如果不是这样。您可以使用更多详细信息更新您的问题:)

答案 3 :(得分:0)

如果在isAuthenticated为true时需要使用updateLogin,则可以添加useEffect挂钩。

像这样

environ("appdata")