#reactjs #redux #react-redux #redux-toolkit #rtk-query
Вопрос:
Как вы передаете параметры запроса в api с помощью RTK-запроса Redux Toolkit?
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
const baseUrl = 'xxxxxxx';
export const postsApi = createApi({
reducerPath: 'posts',
baseQuery: fetchBaseQuery({ baseUrl }),
endpoints: (builder) => ({
getPostsByYear: builder.query({
query: (start, end) => { // Why is 'end' always undefined???
return {
url: 'posts/',
params: { start, end },
};
},
}),
getPosts: builder.query({
query: () => 'posts/',
}),
getPostByID: builder.query({
query: (name) => `posts/${name}`,
}),
}),
});
export const { useGetPostsQuery, useGetPostsByYearQuery, useGetPostByIDQuery } = postsApi;
При попытке передать параметры из компонента распознается только start
значение. year
обновляется выбранным элементом внутри <PostOptions/>
компонента. Он использует useState
крюк. Значение обновляется правильно и useGetPostsByYearQuery
вызывается, но end
параметр всегда не определен. Итак, похоже, я неправильно определяю конечную точку api. Есть какие-нибудь советы? Все, что я хочу, чтобы он сделал, это отправил запрос в форме http://xxx/posts?start=startamp;end=end
.
Я даже пытался жестко закодировать строковое значение для end
параметра, например useGetPostsByYearQuery(year, '2019')
, но оно все равно отображается как undefined
при обратном вызове api, поэтому мне не хватает чего-то более фундаментального.
const Post = () => {
const year = useSelector((state) => state.postOptions.year);
const yearPlusOne = parseInt(year, 10) 1;
const { data, error, isLoading } = useGetPostsByYearQuery(year, yearPlusOne);
return (
<SafeAreaView style={styles.container}>
<View style={styles.content}>
<PostHeading />
<PostOptions></PostOptions>
</View>
</SafeAreaView>
);
};
export default Post;
Комментарии:
1. мало что можно добавить к ответу от @slideshowp2, кроме этого:
query
всегда требуется только один аргумент, вот почемуend
у вас были проблемы. Ответ ниже очень хорошо показывает, как это обойти 🙂
Ответ №1:
Это QueryArg
универсальный тип.
interface EndpointDefinitionWithQuery<
QueryArg,
BaseQuery extends BaseQueryFn,
ResultType
> {
query(arg: QueryArg): BaseQueryArg<BaseQuery>
}
См. Исходный код.
Из документов, Определяющих конечные точки запроса:
Если
query
для обратного вызова требуются дополнительные данные для создания URL-адреса, его следует записать так, чтобы он принимал один аргумент. Если вам нужно передать несколько параметров, передайте их в формате одного «объекта параметров».
Таким образом, вы можете объявить универсальный QueryArg
тип параметра для builder.query
метода, подобного этому:
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
const baseUrl = 'xxxxxxx';
export const postsApi = createApi({
reducerPath: 'posts',
baseQuery: fetchBaseQuery({ baseUrl }),
endpoints: (builder) => ({
getPostsByYear: builder.query<any, { start: string; end: string }>({
query: (arg) => {
const { start, end } = arg;
console.log('arg: ', arg);
return {
url: 'posts/',
params: { start, end },
};
},
}),
}),
});
export const { useGetPostsByYearQuery } = postsApi;
И передайте запрос arg следующим образом:
import React from 'react';
import { useGetPostsByYearQuery } from './hooks';
export default function App() {
const { data, error, isLoading } = useGetPostsByYearQuery({ start: '2019', end: '2021' });
return <div>app</div>;
}
Журнал:
arg: { start: '2019', end: '2021' }
версия: "@reduxjs/toolkit": "^1.6.0"