Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React access redux store in axios interceptor

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.enter image description here

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?

like image 500
lo0k Avatar asked May 09 '26 18:05

lo0k


2 Answers

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)
like image 106
markerikson Avatar answered May 12 '26 06:05

markerikson


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/

like image 45
ßiansor Å. Ålmerol Avatar answered May 12 '26 06:05

ßiansor Å. Ålmerol



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!