I want to access redux store in axios's interceptor which configures jwt token, so I import the store into the API.js file. But it immediately logged out some errors.
Here's the axios instance
import axios from "axios";
import { store } from '../redux/store';
export const SERVERURL = "some url";
axios.defaults.withCredentials = true;
const API = axios.create({ baseURL: "some url" });
API.interceptors.request.use(req => {
// something I want to do
return req;
});
export default API;
Here's the store.js
import { configureStore } from "@reduxjs/toolkit";
import userReducer from "./user";
export const store = configureStore({ reducer: { user: userReducer } });
And the index.js
import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";
import "./index.css";
import App from "./App";
import {store} from "./redux/store";
import { Provider } from "react-redux";
ReactDOM.render(
<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>,
document.getElementById("root")
);
I want to know what would be the problem?
It's a circular import dependency issue, caused by trying to directly import the store file into other parts of the codebase. You'll need to avoid doing that.
Per our docs, one recommended option is to add a small injectStore() function to the Axios interceptors file, and inject the store into the interceptors as part of the app setup in index.js:
https://redux.js.org/faq/code-structure#how-can-i-use-the-redux-store-in-non-component-files
// common/api.js
let store
export const injectStore = _store => {
store = _store
}
axiosInstance.interceptors.request.use(config => {
config.headers.authorization = store.getState().auth.token
return config
})
// index.js
import store from './app/store'
import { injectStore } from './common/api'
injectStore(store)
I used this approach.
Create axios instance
services/index.ts
import axios, { AxiosInstance } from 'axios'
const instance: AxiosInstance = axios.create({
baseURL: process.env.NEXT_PUBLIC_API_URL,
headers: {
Accept: 'application/json',
'Content-type': 'application/json',
},
})
export default instance
Create interceptor. Axios instance should be separated from interceptor so you can call the instance separately.
services/interceptor.ts
import { AxiosError, AxiosRequestConfig } from 'axios'
import instance from './index'
const setUpInterceptor = (store: any) => {
const handleError = async (error: AxiosError) => {
return Promise.reject(error)
}
instance.interceptors.request.use(
async (config: any | AxiosRequestConfig) => {
/* your logic here */
return config
}
)
instance.interceptors.response.use((response) => response, handleError)
}
export default setUpInterceptor
Here, all you need to do is to initialize the interceptor in your root js file _app.tsx, app.js or index.js then you can do now your logic in your interceptor.ts
import setUpInterceptor from '@/utils/services/interceptor'
import { useStore } from 'react-redux'
const MyApp = ({ Component, pageProps }: AppProps) => {
const store = useStore()
setUpInterceptor(store) //<-- initialize the interceptor here
return (
<PersistGate persistor={store.__persistor}>
<Component {...pageProps} />
</PersistGate>
)
}
Source: https://www.bezkoder.com/redux-refresh-token-axios/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With