RTK Query如何像处理查询参数一样处理路径变量?
RTK Query 处理路径参数的正确方式
首先明确:RTK Query没有专门的官方API像处理查询参数(params字段)那样自动替换路径变量,你需要手动格式化URL字符串,但有几种简洁的实现方式,下面是具体方案:
方案1:模板字符串直接拼接
这是最直观的方式,利用JavaScript模板字符串直接注入路径变量:
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; const api = createApi({ baseQuery: fetchBaseQuery({ baseUrl: '/' }), endpoints: (builder) => ({ getUserRecommendations: builder.query({ query: ({ id, type }) => ({ url: `v2/users/${id}/recommendations/${type}`, method: 'GET', }), }), }), }); // 使用时传入参数 const { data } = useGetUserRecommendationsQuery({ id: 123, type: 'movies' });
方案2:封装路径替换工具函数
如果有大量带路径变量的端点,可以封装一个通用函数来统一处理,避免重复拼接:
// 工具函数:替换URL中的占位符 const replacePathVariables = (urlTemplate, variables) => { return urlTemplate.replace(/\{(\w+)\}/g, (_, key) => variables[key]); }; // 在API定义中使用 const api = createApi({ baseQuery: fetchBaseQuery({ baseUrl: '/' }), endpoints: (builder) => ({ getUserRecommendations: builder.query({ query: (params) => ({ url: replacePathVariables('v2/users/{id}/recommendations/{type}', params), method: 'GET', }), }), }), });
方案3:结合baseQuery自定义扩展
如果需要全局统一处理路径变量,可以在baseQuery中扩展逻辑,比如拦截请求并替换占位符:
const customBaseQuery = async (args, api, extraOptions) => { let url = args.url; // 如果有路径变量参数,替换占位符 if (args.pathVariables) { url = url.replace(/\{(\w+)\}/g, (_, key) => args.pathVariables[key]); // 移除pathVariables,避免干扰其他逻辑 delete args.pathVariables; } // 调用原生fetchBaseQuery return fetchBaseQuery({ baseUrl: '/' })({ ...args, url }, api, extraOptions); }; const api = createApi({ baseQuery: customBaseQuery, endpoints: (builder) => ({ getUserRecommendations: builder.query({ query: ({ id, type }) => ({ url: 'v2/users/{id}/recommendations/{type}', method: 'GET', pathVariables: { id, type }, }), }), }), });
注意事项
- 路径变量的值要确保是合法的URL字符,必要时可以用
encodeURIComponent()处理,避免URL编码问题:url: `v2/users/${encodeURIComponent(id)}/recommendations/${encodeURIComponent(type)}` - 不要混淆路径变量和查询参数:如果同时需要路径变量和查询参数,可以在
query中同时返回url(含路径变量)和params(查询参数):query: ({ id, type, page }) => ({ url: `v2/users/${id}/recommendations/${type}`, method: 'GET', params: { page }, // 会自动拼接成?page=1这样的查询参数 })
内容的提问来源于stack exchange,提问作者Elyasaf755
相关产品推荐
相关产品推荐

