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

在异步请求函数中使用UseDispatch Hook报错,求解决方案

问题原因

你遇到的错误是因为React Hook只能在React组件函数或自定义Hook的顶层调用,而fetchService是普通异步函数,直接使用useAppDispatch违反了Hook的使用规则。


解决方案

方案1:将dispatch作为参数传入fetchService

修改fetchService的参数定义,把组件中获取的dispatch传递进来使用:

const fetchService: ({}: {
  token?: string
  url: string
  method?: string
  addContentTypeApplicationJson?: boolean
  body?: any
  formData?: any
  options?: any
  dispatch: ReturnType<typeof useAppDispatch>
}) => Promise<{ data: any; status: number }> = async ({
  token = '',
  url,
  method = 'GET',
  body = {},
  dispatch,
}) => {
  let status: number
  const headers: any = {
    'end-username': UserService.getUsername(),
    Authorization: 'Bearer ' + token,
  }
  dispatch(toggleLoading())
  try {
    const response = await fetch(url, {
      method: method,
      headers: headers,
      body: body,
    })
    status = response.status
    const responseJson = await response.json()
    dispatch(toggleLoading())
    return { status: status, data: responseJson }
  } catch (e) {
    toast.error('Network Error!')
    dispatch(toggleLoading())
    return { status: 500, data: {} }
  }
}
export { fetchService }

组件中调用示例:

const dispatch = useAppDispatch()

// 调用fetchService
fetchService({
  url: '/api/example',
  method: 'POST',
  body: { key: 'value' },
  dispatch: dispatch
})

方案2:封装为自定义Hook

把请求逻辑放到自定义Hook中,这样就能合法使用useAppDispatch:

// 自定义Hook
export const useFetchService = () => {
  const dispatch = useAppDispatch()

  const fetchData = async ({
    token = '',
    url,
    method = 'GET',
    body = {},
  }: {
    token?: string
    url: string
    method?: string
    body?: any
  }): Promise<{ data: any; status: number }> => {
    let status: number
    const headers: any = {
      'end-username': UserService.getUsername(),
      Authorization: 'Bearer ' + token,
    }
    dispatch(toggleLoading())
    try {
      const response = await fetch(url, {
        method: method,
        headers: headers,
        body: body,
      })
      status = response.status
      const responseJson = await response.json()
      dispatch(toggleLoading())
      return { status: status, data: responseJson }
    } catch (e) {
      toast.error('Network Error!')
      dispatch(toggleLoading())
      return { status: 500, data: {} }
    }
  }

  return { fetchData }
}

组件中使用示例:

const { fetchData } = useFetchService()

const handleFetch = async () => {
  const result = await fetchData({
    url: '/api/example',
    method: 'POST',
    body: { key: 'value' }
  })
  // 处理请求结果
}

方案3:直接使用Redux Store实例

如果你的Redux Store是单独导出的(比如在store.ts中),可以直接导入并调用dispatch:

假设store.ts代码:

import { configureStore } from '@reduxjs/toolkit'
import configReducer from './configSlice'

export const store = configureStore({
  reducer: {
    appConfigs: configReducer,
  },
})

export type RootState = ReturnType<typeof store.getState>
export type AppDispatch = typeof store.dispatch

修改fetchService:

import { store } from './store'
import { toggleLoading } from './configSlice'

const fetchService: ({}: {
  token?: string
  url: string
  method?: string
  addContentTypeApplicationJson?: boolean
  body?: any
  formData?: any
  options?: any
}) => Promise<{ data: any; status: number }> = async ({
  token = '',
  url,
  method = 'GET',
  body = {},
}) => {
  let status: number
  const headers: any = {
    'end-username': UserService.getUsername(),
    Authorization: 'Bearer ' + token,
  }
  store.dispatch(toggleLoading())
  try {
    const response = await fetch(url, {
      method: method,
      headers: headers,
      body: body,
    })
    status = response.status
    const responseJson = await response.json()
    store.dispatch(toggleLoading())
    return { status: status, data: responseJson }
  } catch (e) {
    toast.error('Network Error!')
    store.dispatch(toggleLoading())
    return { status: 500, data: {} }
  }
}
export { fetchService }

方案选择建议

  • 方案1:适合需要保持fetchService独立的场景,灵活度高;
  • 方案2:符合React Hook设计理念,适合在组件内复用请求逻辑;
  • 方案3:实现最简单,但服务端渲染(SSR)场景需谨慎使用。

内容的提问来源于stack exchange,提问作者Mohammad Koolivand

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 10:35:35