Redux Toolkit RTK Query 发送查询参数

问题描述

如何使用 Redux Toolkit RTK Query 将查询参数传递给 api?

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/> 组件中的 select 元素更新。它使用 useState 钩子。该值正确更新并调用useGetPostsByYearQuery,但 end 参数始终未定义。所以,似乎我没有正确定义 api 端点。有什么建议吗?我想要它做的就是以 http://xxx/posts?start=start&end=end 的形式发送请求。

我什至尝试硬编码 end 参数的字符串值,例如useGetPostsByYearQuery(year,'2019'),但在 api 回调中它仍然显示undefined,所以我缺少一些更基本的东西。

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;

解决方法

QueryArg 是泛型类型。

interface EndpointDefinitionWithQuery<
  QueryArg,BaseQuery extends BaseQueryFn,ResultType
> {
  query(arg: QueryArg): BaseQueryArg<BaseQuery>
}

source code

来自文档 Defining Query Endpoints

如果 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;

并像这样传递查询参数:

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"