Redux Toolkit RTK Запрос отправка параметров запроса

#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"