我正在使用 react-query 进行 API 调用,在这个问题案例中,我只想在满足某些条件时调用 API。
我有一个输入框,用户可以在其中输入搜索查询。当输入值更改时,将使用输入的内容作为搜索查询调用搜索服务器……但前提是输入值的长度超过 3 个字符。
在我的反应组件中,我正在调用:
const {data, isLoading} = useQuery(['search', searchString], getSearchResults);
Run Code Online (Sandbox Code Playgroud)
我的getSearchResults函数将有条件地进行 API 调用。
const getSearchResults = async (_, searchString) => {
if (searchString.length < 3)
return {data: []}
const {data} = await axios.get(`/search?q=${searchString}`)
return data;
}
Run Code Online (Sandbox Code Playgroud)
我们不能在条件中使用钩子 - 所以我将条件放入我的 API 调用函数中。
这几乎有效。如果我输入一个简短的查询字符串,则不会发出 API 请求,并且会返回一个空数组data。好极了!
但是 -isLoading会true短暂地翻转- 即使没有发出 HTTP 请求。所以我的加载指示器会在没有实际网络活动时显示。
我是否误解了如何最好地解决我的用例,有没有办法确保isLoading在没有 HTTP 活动的情况下返回 false?
正如标题所示,我是使用 useQuery 和相关库的新手,我尝试使用它来获取数据,然后填充我创建的字段列表但是当我运行它时,我在发出两个请求后收到此错误
Missing queryFn index.js:1
e index.js:1
onError query.js:356
reject retryer.js:67
run retryer.js:132
(Async: promise callback)
run retryer.js:116
Retryer retryer.js:156
fetch query.js:330
executeFetch queryObserver.js:199
onSubscribe queryObserver.js:40
subscribe subscribable.js:16
useBaseQuery useBaseQuery.js:60
React 5
unstable_runWithPriority scheduler.development.js:468
React 3
workLoop scheduler.development.js:417
flushWork scheduler.development.js:390
performWorkUntilDeadline scheduler.development.js:157
(Async: EventHandlerNonNull)
js scheduler.development.js:180
js scheduler.development.js:645
Webpack 21
Run Code Online (Sandbox Code Playgroud)
据我所知,我已经传递了一个查询函数,所以我很困惑为什么会显示这个错误,我可以看到服务器正在接收请求并且似乎发送了它,我已经在其他地方进行了测试,并且服务器确实发送了它,所以它必须和我的代码在一起吧?
const URL = 'http://localhost:3500/monster';
const fetchMonster = async (id) => {
console.log(id);
let res = await fetch(`${URL}/${id}`);
if (!res.ok) {
throw new Error('Network response was not ok');
} …Run Code Online (Sandbox Code Playgroud) 我只是在玩反应查询
带打字稿
我的意思是我做了我的第一次尝试
这是正确的方法吗?
const useCreateTodo = () => {
const queryClient = useQueryClient();
return useMutation(
(todo: TodoDto) => axios.post(`${URL}/todos`, todo).then((res) => res.data),
{
onMutate: async (newTodo: TodoDto) => {
// Cancel any outgoing refetches (so they don't overwrite our optimistic update)
await queryClient.cancelQueries("todos");
// Snapshot the previous value
const previousTodos = queryClient.getQueryData("todos");
// Optimistically update to the new value
queryClient.setQueryData<TodoDto[] | undefined>("todos", (old) =>
old ? [...old, newTodo] : old
);
// Return a context object with the snapshotted …Run Code Online (Sandbox Code Playgroud) 我用来react-query v3.13从 API 获取数据。
我想做的是从某个点(例如,单击开始按钮时)定期获取 API,而不是从调用 useQuery 时开始。
我尝试了以下几种方法。
enabled将属性设置false为禁用自动查询,但它也会禁用重新获取。enabled属性的方法true。而且我必须setTimeout自己定期重新获取。enabled属性,true但我找不到禁用初始获取的方法。有什么正确的方法可以做到这一点吗?
我刚刚开始使用 React 查询,并使用它在 ListBooks 组件中使用 useQuery 从服务器获取书籍列表
const { data, error, isLoading, isError } = useQuery("books", getAllBooks);
Run Code Online (Sandbox Code Playgroud)
如何访问任何其他组件中的图书列表?
我已经像这样设置了 QueryClientProvider :
const queryCache = new QueryCache({
onError: (error) => {
console.log(error);
},
});
const queryClient = new QueryClient({ queryCache });
ReactDOM.render(
<React.StrictMode>
<QueryClientProvider client={queryClient}>
<ThemeProvider theme={preset}>
<BrowserRouter>
<App />
</BrowserRouter>
</ThemeProvider>
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
</React.StrictMode>,
document.getElementById("root")
);
Run Code Online (Sandbox Code Playgroud)
我正在寻找 Redux 中 useSelector 的等效项来访问 redux 存储中的数据。
在react-query的快速入门文档中,有以下示例:
// Create a client
const queryClient = new QueryClient();
const App = function () {
return (
// Provide the client to your App
<QueryClientProvider client={ queryClient }>
<Todos />
</QueryClientProvider>
);
};
const Todos = function () {
// Access the client
const queryClient = useQueryClient();
// ...
return (
<>
...
</>
);
};
Run Code Online (Sandbox Code Playgroud)
但我不明白为什么我应该在 Todos 中使用 useQueryClient 挂钩。
// Access the client
const queryClient = useQueryClient();
Run Code Online (Sandbox Code Playgroud)
我的意思是我不能queryClient从主文件中导出实例:
// App.js
export const queryClient …Run Code Online (Sandbox Code Playgroud) 我觉得文档中有关于设置默认选项的提示useQuery,但我无法弄清楚具体如何设置。例如,QueryClient 采用defaultOptions构造函数,但不清楚如何将其附加到useQuery. 也许这是不可能的?
我是新来的反应查询并且到目前为止很喜欢它。我知道它主要是一个 UI 库。所以它非常适合处理/显示错误、加载状态。但我经常发现自己想要以异步方式等待某些特定操作。因此,我希望能够在触发操作(例如重定向)之前等待承诺返回。
这是一个例子:
const NewPostForm = props => {
const history = useHistory();
const mutatePostInfo = useUpdatePost(); // useMutate hook
const [value, setValue] = useState("")
const handleSubmit = () => {
mutatePostInfo.mutate(value);
// I WANT TO: wait for the action to complete before redirecting
history.push("/new-route/")
}
return (
<form onSubmit={handleSubmit}>
<input value={value} onChange={(e) => setValue(e.target.value)} />
</form>
)
}
Run Code Online (Sandbox Code Playgroud) 我有一个自定义useMutation钩子:
const {
status: updateScheduleStatus,
reset: updateScheduleReset,
mutateAsync: updateSchedule,
} = useUpdateSchedule(queryClient, jobId as string);
Run Code Online (Sandbox Code Playgroud)
据我所知,它设置了突变,但是如果我想做多个并行突变,我将如何使用它?
我尝试实现以下内容,但突变在到达线路之前执行Promise.all(mutations。
let mutations: Array<any> = [];
schedulesForDeletion.forEach(async (schedule) => {
const resp = await monitoringService?.getSchedule(
schedule.schedule_id,
);
mutations.push(
updateSchedule({
monitoringService: monitoringService as MonitoringServiceClient,
schedule,
etag: resp?.type === "data" ? resp.headers.etag : "",
}),
);
});
console.dir(mutations);
await Promise.all(mutations);
Run Code Online (Sandbox Code Playgroud)
我会通过mutateAsync返回 a来Promise表示它们不会按顺序开火,但似乎会按顺序开火。
有没有办法处理这个问题,react-query或者我最好用 axios 来执行这个操作?这样做会很有用,react-query因为我需要在突变成功时使某些查询无效。
我已经在使用React Query库的项目上实现了无限滚动。
到目前为止,一切都很好。useInfiniteScroll使用钩子一切都按预期工作
我遇到的一个问题是这个库的缓存机制。如果我查询资源,例如: GET /posts/,将触发 GET /posts/?page=0,向下滚动一点,获取下一个结果, GET/posts/?page=1完全没问题。如果我将搜索参数添加到页面将执行 GET /posts/?filter=someValue&page=0。一切都很好...但是当我filter从搜索中删除它时,它会自动执行 GET /posts/?page=0& GET/posts/?page=1
remove()解决方案是使用查询本身的方法从缓存中删除查询。但这意味着我必须为每个查询手动执行此操作。
我希望获得一个涵盖所有情况的更好的解决方案。我有一个 queryWrapper 我想在其中处理这个问题。
我尝试使用 queryClient 实例invalidateQueries,resetQueries但似乎没有人能够将其从缓存中删除......
在下面的示例中,我保留了ref参数,如果它们发生更改,我可以触发查询以通过useLayoutEffect钩子重置。这部分按预期工作
无效查询尝试
queryClient.invalidateQueries(
[queryKey, JSON.stringify(paramsRef.current)],
{
exact: true,
refetchActive: false,
refetchInactive: false
},
{ cancelRefetch: true }
);
Run Code Online (Sandbox Code Playgroud)
重置查询尝试
queryClient
.resetQueries([queryKey, JSON.stringify(paramsRef.current)], {
refetchPage: (page, index) => index === 0
})
Run Code Online (Sandbox Code Playgroud)
我什至尝试了queryClient.clear()应该从缓存中删除所有现有查询的方法,但页码仍然以某种方式保留在缓存中...我使用useQueryClient钩子访问 queryClient。如果我检查它,我可以看到里面的查询。
有人可以帮我解决这个缓存问题吗?谢谢!
react-query ×10
reactjs ×8
javascript ×3
fetch ×2
react-hooks ×2
promise ×1
promise.all ×1
swr ×1