createListenerMiddleware is a feature from Redux Toolkit that allows you to listen for actions or state changes and run side effects.
Why was it created?
Before createListenerMiddleware, developers typically used:
- useEffect
- Custom middleware
- Redux Thunk
- Redux Saga
- Redux Observable
for side effects.
Redux Toolkit introduced createListenerMiddleware as a simpler alternative for many common use cases.
There are two Ways to Listen:-
- By Action
startListening({
actionCreator: addItem,
effect: () => {
console.log('Item added')
}
})
Runs only when:
dispatch(addItem())
//is dispatched.
2.By Predicate
startListening({
predicate: (_, currentState, previousState) =>
currentState.cart.items.length >
previousState.cart.items.length,
effect: () => {
console.log('Cart grew')
}
})
Runs whenever the cart gets bigger, regardless of which action caused it.
What does startListening() do?
It registers a listener.
listenerMiddleware.startListening({
actionCreator: someAction,
effect: () => {
// side effect
}
})
Similar to:
Listen for someAction
↓
When it happens
↓
Run effect
What can you do inside the effect?
You get access to a listenerApi.
effect: async (action, listenerApi) => {
listenerApi.dispatch(fetchUser())
const state = listenerApi.getState()
await listenerApi.delay(3000)
console.log(state)
}
// we can also Cancel Running Effects
//listenerApi.cancelActiveListeners()
Where is it added?
In your store configuration:
export const listenerMiddleware =
createListenerMiddleware()
export const store = configureStore({
reducer,
middleware: getDefaultMiddleware =>
getDefaultMiddleware().prepend(
listenerMiddleware.middleware
)
})
Simple Definition
createListenerMiddleware is a Redux Toolkit middleware that lets you:
- Listen for specific actions (actionCreator)
- Listen for specific state transitions (predicate)
- Execute side effects (effect)
without putting that logic inside React components. It helps keep application behavior separate from UI behavior.
Let's understand what happens when you dispatch an action in Redux.
Without Middleware
When you do:
dispatch(addItem(product))
Redux follows this flow:
dispatch(action)
↓
reducer
↓
new state
What is Middleware?
Middleware is code that sits between:
dispatch()
and
reducer()
Think of it as a security checkpoint at an airport.
In Redux:
Action
↓
Middleware
↓
Reducer
Every dispatched action passes through middleware first.
Why Does the Predicate Have Access to Both States?
Because listener middleware watches the entire process.
Imagine it takes a snapshot:
const previousState = store.getState()
before the reducer runs.
Then after the reducer:
const currentState = store.getState()
Now it can compare:
predicate(
action,
currentState,
previousState
)
//Example:
predicate: (_, current, previous) =>
!previous.auth.isLoggedIn &&
current.auth.isLoggedIn
we mean it participates in the dispatch pipeline and has visibility into the action and the state transition, allowing it to react after the state changes. That's what makes Predicate & Effect possible.
Top comments (0)