You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将异步获取的Audius服务地址传入Redux Toolkit Query的createApi配置

解决方案

首先需要修正你写的getHost函数的基础问题:函数没有返回值,所以调用后无法拿到host结果,修正后代码如下:

async function getHost() {
  const sample = (arr) => arr[Math.floor(Math.random() * arr.length)]
  const host = await fetch('https://api.audius.co')
    .then(r => r.json())
    .then(j => j.data)
    .then(d => sample(d))
  return host // 新增返回值
}

下面提供两种适配Redux Toolkit Query的实现方案,均不需要在组件内使用useState,不会产生额外性能损耗:


方案1:动态baseQuery(推荐,侵入性最小)

自定义baseQuery逻辑,首次请求时自动拉取最优host并全局缓存,后续所有请求复用缓存结果,现有hooks调用逻辑完全不需要修改:

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'

// 全局缓存host,避免重复请求拉取节点列表
let cachedHost = null
const audiusVersion = `/v1`
const appName = `app_name=ZION`
const section = [`/users`, `/playlists`, `/tracks`]
const search = `/search?query=`

async function getHost() {
  if (cachedHost) return cachedHost
  const sample = (arr) => arr[Math.floor(Math.random() * arr.length)]
  const host = await fetch('https://api.audius.co')
    .then(r => r.json())
    .then(j => j.data)
    .then(d => sample(d))
  cachedHost = host
  return host
}

// 自定义动态baseQuery,首次执行自动获取host
const dynamicBaseQuery = async (args, api, extraOptions) => {
  const host = await getHost()
  const baseUrl = host + audiusVersion
  const rawBaseQuery = fetchBaseQuery({ baseUrl })
  return rawBaseQuery(args, api, extraOptions)
}

export const audiusApi = createApi({
  reducerPath: 'audiusApi',
  baseQuery: dynamicBaseQuery, // 替换为自定义动态baseQuery
  endpoints: (builder) => ({
    searchUsers: builder.query({
      // 注意新增&拼接参数,避免query参数格式错误
      query: (searchQuery) => `${section[0]}${search}${searchQuery}&${appName}`
    }),
    // 其余原有endpoints代码保持不变
  }),
})

// 原有导出的hooks完全不变,可正常使用
export const {
  useSearchUsersQuery,
  useGetUserQuery,
  useGetUsersFavTracksQuery,
  useGetUsersRepostsQuery,
  useGetUserMostUsedTagsQuery,
  useGetUserTracksQuery,
  useSearchPlaylistQuery,
  useGetPlaylistQuery,
  useGetPlaylistTracksQuery,
  useSearchTracksQuery,
  useTrendingTracksQuery,
  useGetTrackQuery,
  useStreamTrackQuery
} = audiusApi

方案2:预初始化host再创建API

应用启动时先拉取最优host,再初始化RTK Query实例和Redux store,所有请求无需额外判断逻辑,性能最优:

第一步:封装API创建逻辑

// audiusApi.js
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
const audiusVersion = `/v1`
export const appName = `app_name=ZION`
export const section = [`/users`, `/playlists`, `/tracks`]
export const search = `/search?query=`

// 接收host参数动态创建API实例
export const createAudiusApi = (host) => {
  const baseUrl = host + audiusVersion
  return createApi({
    reducerPath: 'audiusApi',
    baseQuery: fetchBaseQuery({ baseUrl }),
    endpoints: (builder) => ({
      searchUsers: builder.query({
        query: (searchQuery) => `${section[0]}${search}${searchQuery}&${appName}`
      }),
      // 其余原有endpoints代码保持不变
    })
  })
}

第二步:改写store初始化逻辑

// store.js
import { configureStore } from '@reduxjs/toolkit'
import { createAudiusApi } from './audiusApi'

export default async function initStore() {
  // 先拉取最优host
  const sample = (arr) => arr[Math.floor(Math.random() * arr.length)]
  const host = await fetch('https://api.audius.co')
    .then(r => r.json())
    .then(j => j.data)
    .then(d => sample(d))
  // 动态创建API实例
  const audiusApi = createAudiusApi(host)
  // 初始化store
  const store = configureStore({
    reducer: {
      [audiusApi.reducerPath]: audiusApi.reducer,
      // 其余你的业务reducer保持不变
    },
    middleware: (getDefaultMiddleware) =>
      getDefaultMiddleware().concat(audiusApi.middleware),
  })
  return { store, audiusApi }
}

第三步:改写应用入口逻辑

// main.jsx (对应你的应用入口文件)
import React from 'react'
import ReactDOM from 'react-dom/client'
import { Provider } from 'react-redux'
import App from './App'
import initStore from './store'

initStore().then(({ store, audiusApi }) => {
  // 可将API导出的hooks挂载到全局变量供组件调用,也可按你的项目规范导出
  window.audiusHooks = audiusApi
  ReactDOM.createRoot(document.getElementById('root')).render(
    <Provider store={store}>
      <App />
    </Provider>
  )
})

注意事项:原有参数拼接逻辑存在问题,appName前需要添加&符号避免query参数拼接错误。

内容的提问来源于stack exchange,提问作者Giacomo Gagliano

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 07:54:06