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
相关产品推荐
相关产品推荐

