Reputation: 35038
subscribe
for vanilla Redux here:Where to write to localStorage in a Redux app?
How to subscribe to state outside React component in Redux Toolkit?
What do you think?
Right now I have this simple solution, one reducer, it saves to state and to localStore also, I do not face any issue yet. Shall I change?
extraReducers: (builder) => {
builder
.addCase(me.fulfilled, (state, { payload }) => {
state.authnRes = payload
localStorage.setItem('authnRes', JSON.stringify(payload))
})
Shall I make a separate thunk, and move the localStorage.setItem('authnRes', JSON.stringify(payload))
into there?
He says:
Reducer is never an appropriate place to do this because reducers should be pure and have no side effects.
Do you see any drawback in this approach? Thunk fires an other thunk with local store operation.
export const loginEmail = createAsyncThunk(
`${namespace}/loginEmail`,
async (req: any, { dispatch }) => {
const { data } = await axios(req).then((res) => {
dispatch(persistAuthnUser(res.data)) // <--- here
return res
})
return data
}
)
and here persist
happens:
export const persistAuthnUser = createAsyncThunk(
`${namespace}/persistAuthnUser`,
async (data: any, { dispatch }) => {
return Promise.resolve().then(function () {
localStorage.setItem('authnRes', JSON.stringify(data))
})
}
)
Upvotes: 0
Views: 636
Reputation: 6762
I managed to make it work implementing a middleware:
import {
isAsyncThunkAction,
isPending,
isRejected,
isFulfilled,
isAnyOf,
createListenerMiddleware,
} from '@reduxjs/toolkit'
const sessionListenerMiddleware = createListenerMiddleware()
sessionListenerMiddleware.startListening({
matcher: isAnyOf(isAsyncThunkAction(me)), // execute middleware every time "me" is dispatched
effect: (action, listenerApi) => {
// listenerApi.getState() // You can also access state using this function
const shouldSaveSession = isFulfilled(me) // save session every time async thunk "me" is fulfilled
if (shouldSaveSession(action)) {
// Middleware is executed after reducer, so we can assume state is already updated
localStorage.setItem('authnRes', JSON.stringify(action.payload))
}
},
})
export const sessionMiddleware = sessionListenerMiddleware.middleware
Dont forget to add the middleware to your store:
export const store = configureStore({
reducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware()
.concat(otherMiddlewareYouMightHave)
.concat(sessionMiddleware), // concat it here
})
Upvotes: 0