简体   繁体   English

useEffect 与 function 一起更新 state 作为依赖导致无限循环

[英]useEffect with function that update the state as dependency leads to infinite loop

Code Sandbox: https://codesandbox.io/s/new-breeze-d260k代码沙箱: https://codesandbox.io/s/new-breeze-d260k

The code:编码:

  • This is a simple auth app这是一个简单的身份验证应用程序
  • When you click Login , the accessToken is exchanged and stored in memory while the refreshToken is stored in localStorage.单击Login时,accessToken 被交换并存储在 memory 中,而 refreshToken 存储在 localStorage 中。
  • While the accessToken is valid (here a timestamp), the Home page shows the protected content虽然 accessToken 有效(此处为时间戳),但主页显示受保护的内容
  • At every page reload (ie App initialization), the refreshToken is sent to the server and if it is valid, a new accessToken is exchanged.在每次页面重新加载(即应用程序初始化)时,都会将 refreshToken 发送到服务器,如果有效,则交换新的 accessToken。

The problem:问题:

  • To refresh the token on App initialization, I have an onRefreshToken() function in a useEffect to be executed once (I wanted to pass an empty array as dependency but typescript/eslint complains and suggest that onRefreshToken() should be the dependency. I admit that I don't understand why this is recommended to have always a dependency when you want the effect to be executed once).为了在应用程序初始化时刷新令牌,我在 useEffect 中有一个onRefreshToken() function 要执行一次(我想将一个空数组作为依赖项传递,但 typescript/eslint 抱怨并建议onRefreshToken()应该是依赖项。我承认我不明白为什么当您希望效果执行一次时建议始终具有依赖项)。
  • Once the token is renewed, I store the accessToken and the user profile in their respective context.更新令牌后,我将 accessToken 和用户配置文件存储在各自的上下文中。
  • Infinite re-render loop begins.无限重新渲染循环开始。 On my local server, this is due to setProfile() and not setAccessToken() .在我的本地服务器上,这是由于setProfile()而不是setAccessToken() However I don't understand why.但是我不明白为什么。

Side note边注

The above issue is the main issue of this post but on a side note, the login/logout process don't sync between tabs so if you have any idea why, I would be happy to hear your advice on this point as well.上述问题是这篇文章的主要问题,但附带说明一下,登录/注销过程不会在选项卡之间同步,所以如果您知道原因,我也很乐意听到您在这一点上的建议。

Happy new year新年快乐

One way to fix this would be to check to see if you have an access token and only refresh it if you need to:解决此问题的一种方法是检查您是否有访问令牌,并且仅在需要时才刷新它:

export default function App() {
  const { accessToken } = useAuthContext();
  const { onRefreshToken, onSyncLogin, onSyncLogout } = useAuth();

  useEffect(() => {
    const refresh = async () => {
      await onRefreshToken();
    };
    !accessToken && refresh();
  }, [onRefreshToken, accessToken]);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM