I store logged in user data in localstorage. I also validate JWT token in axios interceptor and if it's expired I will refresh it. so I need to update store with new user data and JWT token and in order to do that, I need to call redux action that I have in my Auth module.
AuthRedux.js
export const actionTypes = {
Login: "[Login] Action",
Logout: "[Logout] Action",
UserRequested: "[Request User] Action",
UserLoaded: "[Load User] Auth API",
SetUser: "[Set User] Action",
};
const initialAuthState = {
user: undefined,
authToken: undefined,
};
export const reducer = persistReducer(
{ storage, key: "myapp-auth", whitelist: ["user", "authToken"] },
(state = initialAuthState, action) => {
switch (action.type) {
case actionTypes.Login: {
const { authToken } = action.payload;
return { authToken, user: undefined };
}
case actionTypes.Logout: {
// TODO: Change this code. Actions in reducer aren't allowed.
return initialAuthState;
}
case actionTypes.UserLoaded: {
const { user } = action.payload;
return { ...state, user };
}
case actionTypes.SetUser: {
const { user } = action.payload;
return { ...state, user };
}
default:
return state;
}
}
);
export const actions = {
login: (authToken) => ({ type: actionTypes.Login, payload: { authToken } }),
logout: () => ({ type: actionTypes.Logout }),
requestUser: (user) => ({ type: actionTypes.UserRequested, payload: { user } }),
fulfillUser: (user) => ({ type: actionTypes.UserLoaded, payload: { user } }),
setUser: (user) => ({ type: actionTypes.SetUser, payload: { user } }),
};
export function* saga() {
yield takeLatest(actionTypes.Login, function* loginSaga() {
yield put(actions.requestUser());
});
yield takeLatest(actionTypes.UserRequested, function* userRequested() {
const { data: user } = yield getUserByToken();
yield put(actions.fulfillUser(user));
});
}
AxiosInterceptor.js
export default function setupAxios(axios, store, props) {
axios.interceptors.request.use(
config => {
const {
auth: { authToken }
} = store.getState();
if (authToken) {
config.headers.Authorization = `Bearer ${authToken}`;
}
return config;
},
err => Promise.reject(err)
);
axios.interceptors.response.use(
(response) => {
console.log(props);
return response;
},
function (error) {
const originalRequest = error.config;
if (error.response?.status === 401) {
if (error.response.data === "refresh_token") {
// refresh token and set new user data
// question is how can I call redux setUser action in here and update state
}
else if (error.response.data === "invalid_token") {
window.localStorage.clear();
window.location.href = '/auth/login';
}
else { }
}
if (!originalRequest._retry) {
originalRequest._retry = true;
return axios(originalRequest);
}
return Promise.reject(error);
}
);
}
My question is how can I call reducer setUser
action in interceptor and update state
question from:
https://stackoverflow.com/questions/65899023/call-redux-action-in-axios-interceptor 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…