首页 > 解决方案 > 使用反应钩子在身份验证过程中进行无休止的刷新

问题描述

我想用 React 和 React Router 实现一个身份验证过程,当每次更改路由但遇到无休止的刷新时,它调用 API 来刷新令牌。

const location = useLocation(); // react-router

const [auth, setAuth] = useState({ accessToken: 'aaa', refreshToken: 'bbb' }); // token-based auth

const refresh = useCallback(async () => {
  const response = await fetch(url, auth.accessToken, auth.refreshToken); // pseudo code
  const body = await response.json();
  setAuth({ accessToken: body.accessToken, refreshToken: body.refreshToken });
}, [auth, setAuth]);

useEffect(() => {
  Promise.resolve().then(refresh);
}, [location.pathname, refresh]);

当路线(location.pathname)改变时,

useEffect被调用(因为它取决于location.pathname),

auth已更新(通过setAuth),

refresh已更新(因为它取决于auth),

useEffect再次调用(因为它取决于refresh),然后继续。

auth和之间的递归依赖refresh导致了这个无限循环。如何解决?

标签: reactjsreact-routerreact-hooks

解决方案


根据 HMR 的回答粘贴我的最终代码以供参考,谢谢。

const fetchAuth = useCallback(async ({ accessToken, refreshToken }) => {
  const resp = await fetch(...);
  const body = await resp.json();
  return {
    accessToken: body.accessToken,
    refreshToken: body.refreshToken,
  };
}, []);

const onRouteChange = useCallback(async () => {
  setAuth((auth) => {
    setTimeout(async () => {
      const accessToken = auth.accessToken;
      const refreshToken = auth.refreshToken;
      const newAuth = await fetchAuth({ accessToken, refreshToken });
      setAuth(newAuth);
    }, 100);
    return auth;
  });
}, [fetchAuth]);

useEffect(() => {
  onRouteChange();
}, [location.pathname, onRouteChange]);

推荐阅读