我需要有关react-query库的帮助。我获取一个对象列表,然后对于每个需要从另一个服务获取额外数据的人。我应该如何使用 react-queryuseQuery钩子来做到这一点?
示例 1:
const { data} = useQuery("USERS", fetchUsers);
data.map(user => useQuery(["ACCOUNT", {userId: user.id}],
({userId}) => fetchAccount(userId)));
Run Code Online (Sandbox Code Playgroud)
错误:
ESLint:
useQuery无法在回调中调用React Hook 。React Hooks 必须在 React 函数组件或自定义 React Hook 函数中调用。(反应钩子/钩子规则)
我用来react-query调用API。该调用运行良好,并且每次在输入字段中更新查询值时都会执行该调用。
不幸的是,即使查询为空,它也会触发 API 调用。
例如,当用户加载应用程序时,输入(以及查询)将为空。
如何仅在有查询时触发API调用?
代码
// API call
export async function myQuery(query) {
try {
const res = await ax.get("myapiurl", {
params: { query },
});
return res.data;
} catch {
return null;
}
}
// react-query
const { status, data } = useQuery(
["myquery", { query }],
() => myQuery(query)
);
Run Code Online (Sandbox Code Playgroud) 我有一个简单的应用程序,可以调用 API。我正在使用反应查询来进行获取并缓存数据。然而,即使该函数被包装在 中React.memo,useQuery也会无缘无故地导致多次重新渲染。应该是2个效果图而不是8个。
import React, { memo } from "react";
import logo from "./logo.svg";
import "./App.css";
import { useQuery } from "react-query";
import Axios from "axios";
const fetchTodoList = async (key, id) => {
const { data } = await Axios.get(
`https://jsonplaceholder.typicode.com/posts/`
);
return data;
};
function App() {
const { isLoading, isError, data, error } = useQuery("todos", fetchTodoList);
console.log(isLoading, data);
if (isLoading) {
return <span>Loading...</span>;
}
if (isError) {
return <span>Error: {error.message}</span>;
}
// also …Run Code Online (Sandbox Code Playgroud) 我有一个使用useQueryReact Query的组件,如下所示:
const { data } = useQuery(
["products", selectedStore],
fetchProductsByStoreId
)
Run Code Online (Sandbox Code Playgroud)
selectedStore是一个可以从 UI 更改的本地状态变量,触发对新产品的 API 的请求。我的问题是,我还需要在另一个组件中使用来自请求的数据,最好是通过queryCache.getQueryData,但要做到这一点,我需要提供一个键,不仅是字符串,"Products"而且是整个数组["products", selectedStore]。
另一个组件无权访问selectedStore,所以我的问题是,另一个组件是否可以在不提升selectedStore到全局状态的情况下访问此查询数据?我想将数据保留在其中queryCache而不是提升它。
我有一些资源,让我们称之为 todos。
我有它的列表,用户可以从列表中删除。
在我实现看起来像的 paginaiton 之前
const {data} = useQuery('todos', fetchTodos)
Run Code Online (Sandbox Code Playgroud)
在我删除它的其他地方
const [deleteTodo, deletingMutation] = useMutation(
(id) => deleteTodo(id),
{
onSuccess: (data, deletedTodoId) => {
const { todos } = queryCache.getQueryData<any>('todos');
queryCache.setQueryData('todos', {
todos: todos.filter(todo=>todo.id !== deletedTodoId),
});
},
});
Run Code Online (Sandbox Code Playgroud)
所以在其他地方我只是修改这个名为的数据集 'todos'
但是在我实现 paginaiton 之后,事情变得更加复杂,因为 QueryKey 现在不仅仅是 'todos'而是['todos', page]
所以当我删除 todo 并调用onSuccess此代码时queryCache.getQueryData<any>('todos');,它会返回我undefined- 因为 QueryKey 还包含此页码。
我该如何解决?使用分页的 QueryKey 修改查询数据。
我尝试使用react-query和react-virtual中的无限查询在我的react.js项目中实现无限滚动。但无限查询支持游标和页面。我的 API 不支持页面,它在元数据中有一个限制、偏移量和总计数,如下所示
meta: { limit: 100, offset: 0, total: 1000}
无限查询是否支持限制和偏移?
我关注了一些链接。
https://codesandbox.io/s/github/tannerlinsley/react-virtual/tree/master/examples/infinite-scroll
https://react-query.tanstack.com/docs/guides/infinite-queries
React-Query 一般会返回一些查询状态,例如isLoading, isError。该库保证这些布尔值是稳定的。这意味着如果检查布尔值,我们可以确定数据存在onSuccess。然而,这当然对于 TS 编译器来说还不够。即使在检查之后,它也假设数据可以是undefined。让 TS 编译器知道数据存在的最佳方法是什么?
这是文档中的示例:
function Todos() {
const { isLoading, isError, data, error } = useQuery('todos', fetchTodoList)
if (isLoading) {
return <span>Loading...</span>
}
if (isError) {
return <span>Error: {error.message}</span>
}
// --> The data is now sure to exist
return (
<ul>
{data.map(todo => ( // --> this will not work with the TS compiler.
<li key={todo.id}>{todo.title}</li>
))}
</ul>
)
}
Run Code Online (Sandbox Code Playgroud) 我有一个Dashboard包含子组件的组件,例如Child它使用反应查询。
我有一个针对该Dashboard组件的现有单元测试,该测试开始失败,错误是:
TypeError: queryClient.defaultQueryObserverOptions is not a function
38 | const { locale } = React.useContext(LocaleStateContext);
39 | const options = getOptions(locale);
> 40 | return useQuery(
| ^
41 | rqKey,
42 | async () => {
43 | const result = await window.fetch(url, options);
Run Code Online (Sandbox Code Playgroud)
测试片段:
const queryClient = new QueryClient();
const { getByTestId, getByRole } = render(
<IntlProvider locale="en" messages={messages}>
<QueryClientProvider client={queryClient}>
<Dashboard />
</QueryClientProvider>
</IntlProvider>,
);
Run Code Online (Sandbox Code Playgroud)
我阅读了有关测试的文档:
https://react-query.tanstack.com/guides/testing#our-first-test
但我不想一定要使用,renderHook因为我对结果不感兴趣。 …
我想在react-query的钩子周围创建一个包装器钩子,useQuery以便我可以捕获401错误,尝试刷新访问令牌,如果成功刷新,则使原始查询无效。
我想要做的完整示例在这里: https: //codesandbox.io/s/agitated-booth-hbe12 ?file=/src/App.js
function useMyQUery() {
const queryClient = useQueryClient();
const { tryRefreshToken } = useSession();
const query = useQuery(...arguments);
if (query.isError && query.error?.status === 401) {
tryRefreshToken().then((tokenRefreshSucccessful) =>
queryClient.invalidateQueries("todos")
);
} else {
return query;
}
return {};
}
Run Code Online (Sandbox Code Playgroud)
在我上面链接的示例中,我能够捕获错误,触发函数tryRefetchToken,但挂钩内的函数useSession似乎在设置令牌后不会拾取令牌。
我正在关注React-query的文档,其中包含有关使用 Next.js 13 应用程序目录中的 Hydrate 组件进行服务器端渲染的部分。在本节中,指南从 React 导入缓存对象,如下所示:
import { cache } from 'react';
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试在自己的项目中从 React 导入缓存时,收到一条错误消息“在‘react’中找不到缓存”。
有人可以解释一下为什么我会收到此错误以及如何修复它吗?我需要安装单独的包才能在 React 中使用缓存对象吗?