I have created an api slice like this:
export const authSlice = createApi({
reducerPath: "auth",
baseQuery: fetchBaseQuery({
baseUrl: resolveApiBaseUrl(),
prepareHeaders(headers) {
headers.set("Content-Type", "application/json")
headers.set("X-XSRF-TOKEN", <string>resolveUserToken())
return headers
}
}),
endpoints(builder) {
return {
login: builder.mutation<GymAppResponse, Login>({
query: (payload) => ({
url: "/login",
method: "POST",
body: payload
}),
})
}
})
export const {
useLoginMutation,
} = authSlice
I am getting the user token after login action and store it in localStorage so I can limit user access to some part of my application.
redux toolkit
in order to interact with userToken
and as default state for userToken I want to use localStorage value. So I dont want to write code in my component to check the localStorage and do the necessary logic. I want to use redux so when the userToken
value updated in localStorage, Redux will automatically update the component for me using useEffect(() => {...}, userTokenWhichRetrivedFromRedux)
.mutation
and combine it with redux toolkit! I used to use redux-saga
which I called redux actions
after a success
or fail
request/response.Question: so I am asking all the knowledgeable fellows out there:
redux-persist
is not being actively maintained and I have to use localStorage prgramatically. Is there a package or best practice for handling data which we need to persist after an Api call ?Here is how I did it in a similar use case :
export const authSlice = createSlice({
name: "auth",
initialState,
reducers: {},
extraReducers: (builder) => {
builder
.addMatcher(authApi.endpoints.login.matchFulfilled, (state, action) => {
state.user = action.payload;
})
.addMatcher(authApi.endpoints.logout.matchFulfilled, (state, action) => {
state.user = null;
});
},
});
You can also use the createListenerMiddleware to access a state slice and provide a callback that will execute based on matchers
const authListenerMiddleware = createListenerMiddleware();
authListenerMiddleware.startListening({
matcher: isAnyOf(
authApi.endpoints.login.matchFulfilled,
authApi.endpoints.logout.matchFulfilled
),
effect: (action, listenerApi) => {
if (action.meta.arg.endpointName === "login") {
const user = listenerApi.getState().auth.user;
localStorage.setItem(AUTHENTICATED_USER, JSON.stringify(user));
}
if (action.meta.arg.endpointName === "logout") {
localStorage.removeItem(AUTHENTICATED_USER);
}
},
});