Typescript for Adding Listeners Inside Components #2798
-
The docs outline a pattern of adding listeners inside components: https://redux-toolkit.js.org/api/createListenerMiddleware#adding-listeners-inside-components I know this isn't recommended, but we have a few places in our app code where we need to change local state based on certain redux actions 🙂 Let's take the example code provided from the link above: useEffect(() => {
// Could also just `return dispatch(addListener())` directly, but showing this
// as a separate variable to be clear on what's happening
const unsubscribe = dispatch(
addListener({
actionCreator: todoAdded,
effect: (action, listenerApi) => {
// do some useful logic here
},
})
)
return unsubscribe
}, []) The problem is that the return type of
So far, I've fixed this error by type asserting import { UnsubscribeListener } from '@reduxjs/toolkit';
useEffect(() => {
const unsubscribe = dispatch(
// same code as above
)
return unsubscribe as unknown as UnsubscribeListener;
}, []) This works, but I was wondering if there was a better way / how others have done this. Maybe in the future we could adjust the return type of Happy to make a reproducible codesandbox if it helps! |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
How are you declaring The issue here is that by default, However, middleware may override that return value. As an example, the thunk middleware instead returns whatever the thunk function returns (such as a promise). RTK's listener middleware is typed so that If you follow our recommended pattern for inferring an |
Beta Was this translation helpful? Give feedback.
How are you declaring
dispatch
in this case?The issue here is that by default,
store.dispatch()
returns exactly the action that you passed in, and the types reflect that.However, middleware may override that return value. As an example, the thunk middleware instead returns whatever the thunk function returns (such as a promise).
RTK's listener middleware is typed so that
dispatch(addListener())
should correctly return anUnsubscribeListener
function. However, the basic ReduxDispatch
type doesn't know that. It has to be inferred from the actual type ofstore.dispatch
in your app setup so that the types from the middleware modify the type of the store.If you follow our recommended patte…