【问题标题】:Redux Toolkit Query and pre fetching some datasRedux Toolkit 查询和预取一些数据
【发布时间】:2021-06-27 20:18:24
【问题描述】:

我正在使用 Redux Toolkit Query 从 Audius 服务器获取数据。该服务基于许多 IPFS 节点,最佳实践是查询在特定时刻向其发送 API 请求的性能最佳的服务器。这是 Audius API 文档建议使用的函数来找到正确的服务器:

const sample = (arr) => arr[Math.floor(Math.random() * arr.length)]
  var host = await fetch('https://api.audius.co')
    .then(r => r.json())
    .then(j => j.data)
    .then(d => sample(d))

我需要从此函数获取 url 并将其输入到我使用 createApi 方法的函数中。
我将该函数包装在一个异步函数中,因为它使用了await,但我被困在了 Promise 中。

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

我不知道如何获取这个函数的结果,我知道如何使用 React 组件,使用 useState Hook,但我不想在这里使用它,因为我认为它会减慢进程。
我试图了解如何使用createAsyncThunk,但我无法理解它。
其余代码如下所示:

const contentProvider = `https://discoveryprovider2.audius.co`
const audiusVersion = `/v1`
const appName = `app_name=ZION`
const baseUrl = contentProvider + audiusVersion
const section = [`/users`, `/playlists`, `/tracks`]
const search = `/search?query=`

export const audiusApi = createApi({
  reducerPath: 'audiusApi',
  baseQuery: fetchBaseQuery({ baseUrl: `${baseUrl}` }),
  endpoints: (builder) => ({
    // SEARCH USERS
    // https://discovery-a.mainnet.audius.radar.tech/v1/users/search?query=Brownies&app_name=EXAMPLEAPP
    searchUsers: builder.query({
      query: (searchQuery) => `${section[0]}${search}${searchQuery}${appName}`
    }), 
.........})
  }),
})



export const {
  useSearchUsersQuery,
  useGetUserQuery,
  useGetUsersFavTracksQuery,
  useGetUsersRepostsQuery,
  useGetUserMostUsedTagsQuery,
  useGetUserTracksQuery,
  useSearchPlaylistQuery,
  useGetPlaylistQuery,
  useGetPlaylistTracksQuery,
  useSearchTracksQuery,
  useTrendingTracksQuery,
  useGetTrackQuery,
  useStreamTrackQuery
} = audiusApi

所以基本上我需要将async 函数= 的结果放置到contentProvider
我试着简单地做

var response = getHost() // my async function

var contentProvider = response

但这并没有通过
希望有人能帮我解决这个问题 =)。

【问题讨论】:

  • 所有这一切都取决于您最终想要如何使用该值,老实说,我在这里无法真正读出您的问题。你不需要createAsyncThunk 来获取一个值,如果你还想调度“生命周期操作”,你只会使用它。
  • 我需要为 createApi redux 切片使用 fetchBaserQuery 的值,该切片涵盖了对 Audius API 的所有请求。因为第一个函数为性能最佳的服务器提供端点。

标签: javascript reactjs redux redux-toolkit


【解决方案1】:

所以你想要一个带有动态baseUrl 的 baseQuery。

我们在文档中有一个example on a baseQuery that uses Redux state for the baseUrl

这仍然意味着,您必须将 baseUrl 放入商店。

调整来自the Redux Essentials tutorial的示例:

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

const hostSlice = createSlice({
  name: 'host',
  initialState: null,
  reducers: {
  },
  extraReducers(builder){
    builder.addCase(getHost.fulfilled, (state, action) => {
      return action.payload
    }
  }
})

然后你把你的hostSlice.reducer插入configureStore

const store = configureStore({
  reducer: {
    host: hostSlice.reducer
// more stuff you had before
  }
})

并发送 thunk:

dispatch(getHost())

然后,您的主机将在您调整后的 baseQuery 中通过 getState().host 可用。

【讨论】:

  • 感谢您的回答!我实际上是在按照教程进行操作,但我陷入了导出/导入中……这与我现在按照您的建议陷入困境的情况相同。我将导出添加到const hostSlice 并将其导入为:import { hostSlice } from "../features/audiusProvider/audiusProviderSlice"; 在商店中。但是后来我真的迷路了,为了使用dispatch,我应该在我正在使用RTK查询的文件中添加它调用useDispatch Hook?对不起我的无知?
  • 取决于您何时以及如何调用它。您可以在商店创建后调用它,在这种情况下,您只需执行store.dispatch(getHost()) - 甚至可能在您的商店创建文件中。您也可以在组件中执行此操作,它将是 const dispatch = useDispatch() 后跟 dispatch(getHost())
  • 我尝试将其添加到商店创建文件中:store.dispatch(getHost()) const host = store.getState().host console.log(host); 但我得到了null ......我从我所在的文件中导入了getHost使用createAsyncThunk ...我不知道我做错了什么=(
  • 好吧,如果您在启动请求后立即记录它,它将是null,因为请求需要一段时间。最好看看 Redux Devtools,看看值会在一段时间后从 null 更改为您的主机。
  • 确实 =) 太棒了!!!非常感谢您的帮助 =) 非常感谢 =)
【解决方案2】:

如果我理解你的话,我认为你对如何使用异步函数感到困惑。

您可以轻松使用async await

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

你可以这样称呼它

var result = await getHost();
 
  result.
    then(d => console.log(d));

【讨论】:

  • 事实上,我应该把 var result 放在异步函数中,因为它使用 await 我错了吗?但是然后我们和以前一样......我需要将数据从承诺中获取到变量中。据我了解,要获得实际价值,应该使用 useState 或 redux ...因为如果不是,您总是会得到一个承诺作为响应 ...
  • 我曾经很挣扎,但现在我可以更好地理解它,React 使用 useState,甚至更容易,使用 Redux Toolkit Query。事实上,我可以先创建一个服务(按照 Redux Toolkit tutos 上的建议),然后我可以将数据导入第二个服务文件,但我想有一种更灵活的方法来做到这一点..
猜你喜欢
  • 1970-01-01
  • 2021-10-05
  • 2021-11-06
  • 2021-09-10
  • 2021-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-21
相关资源
最近更新 更多