【问题标题】:React-Query, useQuery is delivering stale dataReact-Query,useQuery 正在提供陈旧的数据
【发布时间】:2021-04-29 23:03:31
【问题描述】:

我只是第一次尝试 react-query,现在我遇到了一些让我非常沮丧的事情。

以下代码:

const userSettingsQueryClientKey = "userSettings_queryClient";

export const UserSettingsContextProvider: React.FC = ({ children }) => {

    const queryClient = useQueryClient();

    const { data } = useQuery(userSettingsQueryClientKey, async () => {
        const request = new GetRequest<UserSettings>("/UserSettings/Get");
        const result = await request.get();
        return result.payload;
    });

    const { mutateAsync } = useMutation(async (settings: UserSettings) => {
        const updateRequest = new VoidPostRequest<UserSettings>("/UserSettings/Update");
        await updateRequest.post(settings);
        return settings;
    }, {
        onSuccess: (newData) => {
            queryClient.setQueryData(userSettingsQueryClientKey, newData);
        }
    })

    return (
        <UserSettingsContext.Provider value={{
            settings: { ...data },
            updateSettings: async (settings: UserSettings) => {
                await mutateAsync(settings);
            },
        }}>
            {children}
        </UserSettingsContext.Provider>
    );
}

我遇到了很多问题

queryClient.setQueryData(userSettingsQueryClientKey, newData);

部分工作。

我现在已经多次正确调试了我的代码。在我的应用流程中:

  1. 设置初始化为{ useOldVersion: true }

  2. 在某个时间点,用户会点击一个复选框,然后用{ useOldVersion: false } 调用updateSettings

  3. 突变正确地将此更新发布到服务器

  4. onSuccess 被调用,正确地将查询状态设置为新值。

但是,在onSuccess 之后,const { data } 我从我的useQuery 调用中得到的仍然是旧的、陈旧的数据。我用调试器验证了前面的所有步骤,现在我真的不确定我哪里出错了。

关于如何从useQuery 调用中正确获取新状态的任何建议?

【问题讨论】:

  • 您的代码看起来不错,来自变异响应的更新是一个有效的概念,请参阅:react-query.tanstack.com/guides/updates-from-mutation-responses 一些小问题是:mutateAsync 需要 try/catch,除非您需要 Promise 链接,否则请使用 mutate。我从来没有将 react-query 中的数据放入上下文中,因为您可以在需要数据时调用 useQuery(或自定义钩子抽象)。它还将使数据保持最新,因为它会在新订户挂载时触发重新获取。您可以制作一个代码框复制来显示您的问题吗?我可以向你保证,突变后的更新确实有效

标签: javascript react-hooks react-query


【解决方案1】:

我刚刚发现了我非常愚蠢的错误。所有的答案都很有帮助,但始终找不到问题。

我的应用看起来像这样:

export default function App() {

  const queryClient = new QueryClient();

  return (
    <QueryClientProvider client={queryClient}>
      <div className="App">
        <h1>Hello CodeSandbox</h1>
        <MyComponent />
        <h2>Start editing to see some magic happen!</h2>
      </div>
    </QueryClientProvider>
  );
}

这意味着查询客户端会不断地重新生成。

当它像这样移出时它可以工作,因此值是持久的:

const queryClient = new QueryClient();

export default function App() {

  return (
    <QueryClientProvider client={queryClient}>
      <div className="App">
        <h1>Hello CodeSandbox</h1>
        <MyComponent />
        <h2>Start editing to see some magic happen!</h2>
      </div>
    </QueryClientProvider>
  );
}

【讨论】:

    【解决方案2】:

    您可以尝试使用 QueryClient 公开的 refetchQueries 方法。 您的代码如下所示:

     const { mutateAsync } = useMutation(async (settings: UserSettings) => {
            const updateRequest = new VoidPostRequest<UserSettings>("/UserSettings/Update");
            await updateRequest.post(settings);
            return settings;
        }, {
            onSuccess: (newData) => {
                queryClient.setQueryData(userSettingsQueryClientKey, newData);
                queryClient.refetchQueries(userSettingsQueryClientKey);// this is new
    
            }
        })
    
    

    【讨论】:

    • 谢谢,我试过了,但似乎也没有帮助。几乎就像无论我在 onSuccess 中尝试什么,查询本身都不在乎。我还尝试了 invalidateQueries 并在查询中的 GET 回调中放置了一个断点,但它也没有被触发。
    【解决方案3】:

    通知查询已更改的推荐方法是使用queryClient.invalidateQueries

    您可以在 RQ docs 中查看示例。

    const { mutateAsync } = useMutation(
      async (settings: UserSettings) => {
        const updateRequest = new VoidPostRequest<UserSettings>("/UserSettings/Update");
        await updateRequest.post(settings);
        return settings;
      },
      {
        onSuccess: (newData) => {
          queryClient.setQueryData(userSettingsQueryClientKey, newData);
          queryClient.invalidateQueries(userSettingsQueryClientKey);
        }
      }
    );
    

    【讨论】:

      猜你喜欢
      • 2017-10-10
      • 2020-12-02
      • 1970-01-01
      • 2016-10-11
      • 1970-01-01
      • 1970-01-01
      • 2020-12-20
      • 2023-02-07
      • 1970-01-01
      相关资源
      最近更新 更多