Please let me know how to wrap the Axios interceptor to catch the api response for token expiry i.e 401 and call a dispatch action for logout from context, I would like to know how to call hooks inside the Axios.
Came up with the following solution but feel this is not the right way to do it and I could see buggy behaviour.
Please let me know how to address this without the solution being anti pattern.
NOTE: I have to call 2 dispatch actions 1) logout will remove all the localstorage values and do router.push to home page 2) Reset cart will set the cart counter value to zero saved in the store.
Created WithAxios component
// WithAxios.js
import { useMemo } from 'react'
import axios from 'axios'
import { useUser } from '../store/User'
import { useCart } from '../store/Cart'
import { RESET_CART } from 'store/Cart/actions'
const WithAxios = ({ children }) => {
const { logout } = useUser();
const { dispatch: dispatchCart } = useCart()
useMemo(() => {
axios.interceptors.response.use(response => {
//console.log('response', response)
return response
}, async (error) => {
if (error.response.status === 401) {
//console.log('response', error)
dispatchCart({
type: RESET_CART,
})
logout()
}
return error;
})
}, [])
return children
}
And wrapped the component after all the context providers in _app.js file, This is a Next js App
import React, { useEffect } from 'react'
import { useCookie } from 'next-cookie'
import '../styles/main.css'
import UserProvider from '../store/User'
import PageProvider from '../store/Page'
import GlobalUIProvider from '../store/GlobalUI'
import BookingProvider from '../store/Booking'
import ExtraProvider from '../store/Extras'
import CartProvider from '../store/Cart'
import CheckoutProvider from '../store/Checkout'
import { useRouter } from 'next/router'
import { storePathValues } from '../utilities/helperFunctions'
import Layout from 'layouts/Layout'
import WithAxios from '../components/WithAxios'
const App = ({ Component: Pages, pageProps, cookie }) => {
const router = useRouter()
const currenCookie = useCookie(cookie)
return (
<>
<PageProvider model={pageProps}>
<GlobalUIProvider>
<UserProvider>
<CartProvider>
<CheckoutProvider>
<BookingProvider>
<ExtraProvider>
<WithAxios>
<Layout
Pages={Pages}
pageProps={pageProps}
cookie={agentCookie}
/>
</WithAxios>
</ExtraProvider>
</BookingProvider>
</CheckoutProvider>
</CartProvider>
</UserProvider>
</GlobalUIProvider>
</PageProvider>
</>
)
}
// NOTE: The limitation of specifying a default layout is that you can't pass serverside props to the component
export async function getServerSideProps(context) {
return {
props: {
cookie: context.req.headers.cookie || '',
},
}
}
export default App