在 redux 教程中,我们学习了如何执行乐观更新:
第 8 部分-rtk-query-advanced#implementing-optimistic-updates
但在updateQueryData的 API 参考中,我发现args必须传入 an :
const updateQueryData = (
endpointName: string,
args: any,
updateRecipe: (draft: Draft<CachedState>) => void
) => ThunkAction<PatchCollection, PartialState, any, AnyAction>;
Run Code Online (Sandbox Code Playgroud)
所以,如果我们的帖子有分页,
getPosts: builder.query({
query: (current: number) => `/posts?current=${current}`,
providesTags: ['Post']
}),
Run Code Online (Sandbox Code Playgroud)
这个时候我们如何进行乐观更新呢?
// Is there a way to update all getPosts caches?
// Am I missing some documents?
apiSlice.util.updateQueryData('getPosts', ???, (draft) => {
const post = draft.find((post) => post.id === postId)
if (post) {
post.reactions[reaction]++
}
})
Run Code Online (Sandbox Code Playgroud) 在我的React应用程序中,我使用RTK查询来获取数据。我有10 多个API 端点以及每个端点的一条路由。
我想在页面顶部显示一条水平线来指示数据收集正在进行。
目前,我已经做到了这一点。
const ArticlePage = () => {
const { id} = useParams();
const { data, isFetching, isLoading } = useFetchArticleByIdQuery(id);
return (
<Layout>
{(isFetching || isLoading) && <LinearProgressIndicator />}
<PageHead />
{data && <ArticleContent article={data} />}
</Layout>
);
};
Run Code Online (Sandbox Code Playgroud)
我也尝试过这个。
const ArticlePage = () => {
const { id} = useParams();
const { data, isFetching, isLoading } = useFetchArticleByIdQuery(id);
return (
<Layout>
<LinearProgressIndicator shouldDisplay={(isFetching || isLoading)} />
<PageHead …Run Code Online (Sandbox Code Playgroud) 我确信我缺少一些简单和基本的东西,但我已经查看了我能找到的所有线程和文档,但没有弄清楚我在这里没有得到什么。我刚刚开始在 React 应用程序上实现 RTK 查询,并且已经一一解决了端点问题。
我有 2 组端点、客户端和合约。在数据库中,合同是客户的子文档。所有调用都工作正常(没有错误,所有结果都已完成),并且标签在客户端端点中无效,但在合同端点中无效。我尝试过使用 ['Contract'] 的简单基本标签,并尝试了下面代码中的内容(以及 id 的一些变体),但所有结果都是相同的 - 必须手动重新加载页面才能重新获取。
我的使用基于此处给出的示例:https ://redux-toolkit.js.org/rtk-query/usage/automated-refetching
再说一次,我确信这是一些简单的事情,我不理解 RTK 查询,但我无法发现它。
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
export const apiSlice = createApi({
reducerPath: 'api',
baseQuery: fetchBaseQuery({ baseUrl: 'http://localhost:5000'}),
tagTypes: ['Client', 'Contract', 'User', 'Visit'],
endpoints: builder => ({
getClients: builder.query({
query: () => '/clientapi/clients',
providesTags: ['Client']
}),
getClient: builder.query({
query: clientId => `/clientapi/clients/${clientId}`,
providesTags: ['Client']
}),
addNewClient: builder.mutation({
query: ({ values }) => ({
url: '/clientapi/clients',
method: 'POST',
body: values
}), …Run Code Online (Sandbox Code Playgroud) 我想将数组作为参数发送,如下所示:
v1/product?main_category[]=3&main_category[]=4
Run Code Online (Sandbox Code Playgroud)
我的参数:
params.main_category = [1,2,3]
Run Code Online (Sandbox Code Playgroud)
我的产品切片:
export const productsSlice = apiSlice.injectEndpoints({
endpoints: (builder) => ({
getProducts: builder.query<
any,
{
title: string;
ename: string;
status: string;
site_product_id: number;
site_product_meta_id: number;
per_page: number;
page: number;
parent_id: [];
main_category: [];
stock_category: [];
side_category: [];
}
>({
query: (arg) => {
const {
title: ename,
status,
site_product_id,
site_product_meta_id,
per_page,
page,
parent_id,
main_category,
stock_category,
side_category,
} = arg;
return {
url: "/product",
params: {
ename,
status,
site_product_id,
site_product_meta_id,
per_page,
page,
parent_id,
main_category,
stock_category,
side_category, …Run Code Online (Sandbox Code Playgroud) redux-toolkit 给出原始文档--
import { configureStore } from '@reduxjs/toolkit'
// Or from '@reduxjs/toolkit/query/react'
import { setupListeners } from '@reduxjs/toolkit/query'
import { pokemonApi } from './services/pokemon'
export const store = configureStore({
reducer: {
// Add the generated reducer as a specific top-level slice
[pokemonApi.reducerPath]: pokemonApi.reducer,
},
// Adding the api middleware enables caching, invalidation, polling,
// and other useful features of `rtk-query`.
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(pokemonApi.middleware),
})
// optional, but required for refetchOnFocus/refetchOnReconnect behaviors
// see `setupListeners` docs - takes an optional …Run Code Online (Sandbox Code Playgroud) 我在用:
dispatch(api.endpoints.getPosts.initiate(undefined))
Run Code Online (Sandbox Code Playgroud)
但我在 redux 中收到以下错误:
name:"ConditionError"
message:"Aborted due to condition callback returning false."
Run Code Online (Sandbox Code Playgroud)
我在这个问题上找到了这个错误的含义:
这意味着 asyncThunk 由于条件而未执行。如果您使用 RTK 查询,这仅意味着跳过了另一个请求,因为已经有一个请求正在运行或缓存中已经有一个值,因此不需要发出任何请求。这是 RTK-Query 用于跟踪组件订阅的内部拒绝,而不是错误。
但是有没有办法强制重新获取呢?
我正在使用 RTK 查询来获取一些数据。我需要访问应用程序中各个组件的加载状态,但我不确定如何执行此操作。
我觉得这可能只是我误解了如何在更大的应用程序中正确使用 RTK 查询。大多数示例都是单个组件,我不太明白如何从各个组件访问单个查询的各种状态。
例如,我需要在应用程序的主要部分显示一个加载程序,其中数据是从查询生成的。然后,我需要在侧边栏的一小部分中显示一个完全不同的加载器,其中包含一些通过相同的 API 查询生成的内容详细信息。
这如何与 RTK 查询配合使用?
是否存在使用共享此查询状态/状态的多个组件的示例?
我是否完全错过了对如何在应用程序中使用状态的基本理解?(我感觉这就是这里的哈哈)
我正在尝试从 createAsuncThunks 迁移到 RTK-Query。在页面加载时,我检查存储中是否没有用户,然后从后端获取用户和其他数据。
此代码与 createAsuncThunks 配合良好,但与 RTK-Query 配合使用效果如何?
const InitApp = () => {
const dispatch = useAppDispatch();
const user = useAppSelector((state) => state.user);
const ignore = useRef(false);
useEffect(() => {
if (!user && !ignore.current) {
Promise.all([
dispatch(getUser()),
dispatch(getRawMedias()),
dispatch(getFaces()),
dispatch(getProjects()),
]);
}
return () => {
ignore.current = true;
};
}, [dispatch, user]);
if (!user) {
return <Loader areaLoader />;
}
return <Outlet />;
};
Run Code Online (Sandbox Code Playgroud)
我认为这种方法是错误的,但目前尚不清楚如何正确地实现它:
const {data} = useGetUserQuery()
useEffect(() => {
if (!data) {
// can't …Run Code Online (Sandbox Code Playgroud) RTK 查询中查询的定义是query<ResultType, QueryArg>。所有这些对于我实际需要向 API 发送参数的查询来说都很好。但是,我有一些端点不需要发送任何内容(例如 getAllX)。我可以在模板中将什么作为 QueryArg 传递?它不会接受任何一个争论。
到目前为止,我已经使用了像undefined和 之类的类型null来表示不需要发送任何内容,但是当您使用 hook: 时它看起来很难看,const {...} = useGetXQuery(undefined)而且我很确定必须有更好的方法,但是在互联网上搜索没有结果。
我想使用 RTK 查询将带有表单数据的图像发送到 Nest js 服务器,但文件未发送。代码是:
uploadImage: builder.mutation<any, any>({
query: (imageFile) => {
var bodyFormData = new FormData();
bodyFormData.append('file', imageFile);
console.log({ bodyFormData, imageFile });
return {
url: '/uploader/image',
method: 'POST',
headers: {
'Content-Type': 'multipart/form-data;'
},
body: { bodyFormData }
};
}
})
Run Code Online (Sandbox Code Playgroud)
我可以使用 Axios 发送图像,但在 RTK 中则不能。