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

Redux Toolkit组件中addListener遇TypeScript错误(createListenerMiddleware)

const dispatch = useDispatch()
useEffect(() => {
return dispatch(
addAppListener({
matcher: isAnyOf(
updateResponse,
...
),
effect: async (action, listenerApi) => {
...
}
})
)
}, [])

同时已完成应用监听器的类型定义:
```js
import { addListener, createListenerMiddleware } from '@reduxjs/toolkit'
import type { TypedAddListener, TypedStartListening } from '@reduxjs/toolkit'
import type { AppDispatch, RootState } from './store'

export const listenerMiddleware = createListenerMiddleware()

export type AppStartListening = TypedStartListening<RootState, AppDispatch>

export const startAppListening =
  listenerMiddleware.startListening as AppStartListening

export const addAppListener = addListener as TypedAddListener<
  RootState,
  AppDispatch
>

但组件中useEffect的返回值出现TypeScript错误:

Argument of type '() => { payload: ListenerEntry<EmptyObject & { user: WritableDraft<UserState>; authentication: AuthenticationState; }, ((action: Action<...>) => UnsubscribeListener) & ... 1 more ... & Dispatch<...>>; type: "listenerMiddleware/add"; }' is not assignable to parameter of type 'EffectCallback'.
  Type '{ payload: ListenerEntry<EmptyObject & { user: WritableDraft<UserState>; authentication: AuthenticationState; }, ((action: Action<...>) => UnsubscribeListener) & ... 1 more ... & Dispatch<...>>; type: "listenerMiddleware/add"; }' is not assignable to type 'void | Destructor'.

请问该错误的原因是什么?


错误原因及解决方案

错误原因

这个错误的核心是**useEffect回调的返回值类型不匹配**:

  • dispatch(addAppListener(...))执行后返回的是一个Redux action对象
  • 但useEffect要求回调的返回值必须是void,或者一个无参数、返回void的清理函数(Destructor)

你直接返回了action对象,违反了TypeScript对EffectCallback的类型约束。

解决方案

修改useEffect逻辑,先获取监听器的取消订阅函数,再将其作为返回值:

import { useDispatch } from 'react-redux'

...
const dispatch = useDispatch()
useEffect(() => {
    // 调用dispatch添加监听器,得到取消订阅函数
    const unsubscribe = dispatch(
      addAppListener({
        matcher: isAnyOf(
          updateResponse,
          ...
        ),
        effect: async (action, listenerApi) => {
           ...
        }
      })
    )
    // 返回取消函数,组件卸载时自动执行清理
    return unsubscribe
  }, [])

你的addAppListener类型定义已经正确使用了TypedAddListener<RootState, AppDispatch>,只要AppDispatch和RootState的类型定义无误,dispatch(addAppListener(...))会自动推导返回值为UnsubscribeListener类型的清理函数,完全符合useEffect的类型要求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 07:47:36