React-Query,useQuery 正在传递陈旧数据

React-Query, useQuery is delivering stale data

我只是第一次尝试 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. 在某个时间点,用户将单击一个复选框,然后调用 updateSettings{ useOldVersion: false }

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

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

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

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

您可以尝试使用 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

        }
    })

通知查询已更改的推荐方法是使用 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);
    }
  }
);

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

我的应用看起来像这样:

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>
  );
}