为什么在卸载/安装操作后我的反应查询查询会重新获取?

Dav*_*res 4 reactjs react-query

设置

我有以下react-query钩子:

const STALE_TIME_MS = 12 * 60 * 60 * 1000; // 12h

const useUser = () => {
  const services = useServices();
  const { isLoading, error, data } = useQuery(
    'user',
    () => services.user.verify(),
    {
      staleTime: STALE_TIME_MS,
      cacheTime: STALE_TIME_MS,
    }
  );
  return {
    isLoading,
    error,
    user: data,
  };
};
Run Code Online (Sandbox Code Playgroud)

然后,我有一个App组件作为一个孩子住在里面QueryClientProvider

const App = () => {
  const { isLoading } = useUser();

  if (isLoading) {
    return <Authenticating />;
  }

  return (
    <HashRouter>
      <Switch>
        <Route path="/login" component={Login} />
        <Route path="/" component={Dashboard} />
      </Switch>
    </HashRouter>
  );
}
Run Code Online (Sandbox Code Playgroud)

Login组件检查用户是否已经登录并将其重定向回/

const Login = () => {
  const { user } = useUser();

  if (user) {
    return <Redirect to="/" />;
  }

  ...
}
Run Code Online (Sandbox Code Playgroud)

Dashboard组件执行相反的操作:

const Dashboard = () => {
  const { user } = useUser();

  if (!user) {
    return <Redirect to="/login" />;
  }

  ...
};

Run Code Online (Sandbox Code Playgroud)

问题

当发出的请求services.user.verify()失败时,react-queryuser无限期地重试查询。尽管 的react-query默认重试次数是 3,但还是如此。

无限重试

问题似乎来自于我useUser()从正在安装/卸载的多个组件调用这一事实。Dashboard当我从和 中删除重定向逻辑时Loginreact-query重试 3 次,然后按预期进入登录屏幕。

一次调用 useUser

有趣的事实是user查询被标记为过时。如果我将services.user.verify()实现更改为 returnnull而不是在用户未经身份验证时抛出错误,则查询将被标记为新鲜,并且我根本没有这个问题。

问题

  • 当查询失败时,即使在重试之后,是否react-query 始终认为查询已过时?
  • 调用查询的新组件是否总是会导致重试?
  • 有没有办法防止这种情况发生?

TkD*_*odo 7

即使在重试之后,react-query 是否总是在查询失败时认为查询已过时?

是的。staleTime仅在成功查询时启动,没有数据的查询(例如因为失败)被认为是过时的。如果您的查询成功一次,然后在重新获取时失败,则它不会自动被视为过时 -staleTime现在很重要,因为您已经拥有数据。

调用查询的新组件是否总是会导致重试?

当组件安装时,react-query 会触发 fetch。这是由于 flag 造成的refetchOnMount,因此如果您不需要,可以自定义此标志。根据retry标志触发重试,是的,如果触发提取,则会相应地触发重试。

有没有办法防止这种情况发生?问题似乎来自于我从正在安装/卸载的多个组件调用 useUser() 的事实。

是的,这似乎是根本原因。您可以使用该refetchOnMount选项解决此问题,或者可能更好 - 不要重定向到调用useUser(并期望用户存在)的路由,除非您已经拥有该用户的数据。例如,Login如果您useUser处于错误状态,您可以安装该组件,因为这意味着您没有经过身份验证,并且仅Dashboard在您有用户时才呈现。