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

等待dispatch thunk执行代码功能正常但编译器告警,求优化方案

优化方案

方案一:修改Thunk类型,解决不必要await告警

步骤1:更新AppThunk类型定义

修改AppThunk的类型,支持自定义返回值,让Thunk可以返回Promise:

// 原定义
// export type AppThunk = ThunkAction<void, RootState, null, Action<string>>

// 修改后
export type AppThunk<ReturnType = void> = ThunkAction<ReturnType, RootState, null, Action<string>>

步骤2:让导出Thunk返回Promise

在ImportExportSlice.ts中,指定导出Thunk的返回类型为AppThunk<Promise<void>>,确保dispatch后能拿到Promise:

export const export = (
  fpNumber?: number,
  errorMsg?: Record<string, string>,
  callback?: (status: string, errorMsg: Record<string, string>) => void
): AppThunk<Promise<void>> => async (dispatch) => {
  await (fpNumber ? importExportApi.export(fpNumber) : importExportApi.export())
    .catch((error) => {
      const statusCode: string = error.response.status.toString()
      dispatch(setExportErrorStatusCode(statusCode))
      callback?.(statusCode, errorMsg)
    })
    .finally(() => dispatch(importExportProtokollLoad()))
}

步骤3:组件中正常使用await

此时dispatch(export(...))会返回合法的Promise,await不再是多余操作,IntelliJ告警消失,同时能正确等待导出完成再关闭加载状态:

const handleOnExport = useCallback(
  async (fpNumber?: number) => {
    setIsExportAktionAktive(true)
    const statusCode2Error: Record<string, string> = {
      '403': I18n.t('...'),
      '423': I18n.t('...')
    }
    try {
      await dispatch(export(fpNumber, statusCode2Error, handleImportExportError))
    } catch (error) {
      console.error(error)
    } finally {
      setIsExportAktionAktive(false)
    }
  },
  [I18n, dispatch, handleImportExportError]
)

方案二:将加载状态存入Slice(更优的集中式状态管理)

如果希望状态统一维护,避免组件分散管理状态,可以把加载状态移到Slice中:

步骤1:在Slice State中添加加载状态

interface ImportExportState {
  // 原有状态字段...
  isExportLoading: boolean
}

const initialState: ImportExportState = {
  // 原有初始值...
  isExportLoading: false
}

步骤2:添加更新加载状态的Action

const importExportSlice = createSlice({
  name: 'importExport',
  initialState,
  reducers: {
    // 原有reducer...
    setExportLoading: (state, action: PayloadAction<boolean>) => {
      state.isExportLoading = action.payload
    }
  }
})

export const { setExportLoading } = importExportSlice.actions

步骤3:修改导出Thunk,自动管理加载状态

export const export = (
  fpNumber?: number,
  errorMsg?: Record<string, string>,
  callback?: (status: string, errorMsg: Record<string, string>) => void
): AppThunk<Promise<void>> => async (dispatch) => {
  dispatch(setExportLoading(true))
  try {
    await (fpNumber ? importExportApi.export(fpNumber) : importExportApi.export())
  } catch (error) {
    const statusCode: string = error.response.status.toString()
    dispatch(setExportErrorStatusCode(statusCode))
    callback?.(statusCode, errorMsg)
  } finally {
    dispatch(importExportProtokollLoad())
    dispatch(setExportLoading(false))
  }
}

步骤4:组件中直接从Store获取加载状态

无需再维护组件内的isExportAktionAktive状态,直接从Store读取:

const isExportLoading = useSelector((state: RootState) => state.importExport.isExportLoading)

const handleOnExport = useCallback(
  async (fpNumber?: number) => {
    const statusCode2Error: Record<string, string> = {
      '403': I18n.t('...'),
      '423': I18n.t('...')
    }
    try {
      await dispatch(export(fpNumber, statusCode2Error, handleImportExportError))
    } catch (error) {
      console.error(error)
    }
  },
  [I18n, dispatch, handleImportExportError]
)

关于useCallback中async/await的说明

async函数作为useCallback的回调是完全合法的,只要依赖项数组配置正确就没有问题。所谓"不佳"的说法通常是指依赖项处理不当导致的不必要重渲染,只要你当前的依赖项[I18n, dispatch, handleImportExportError]是正确的,就无需担心。如果handleImportExportError是组件内定义的函数,记得用useCallback包裹它避免不必要的依赖变化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 18:07:46