we can do either axios.get(url) or axios(url) for GET request.
import { useEffect } from'react'// limit, if 429 wait for 15 min and try againimport axios from'axios'consturl='https://course-api.com/react-store-productss'constfetchData=async () => {try {const { data } =awaitaxios(url)console.log(data) } catch (error) {// if you just do error here, it won't show you the objectconsole.log(error.response) }}constFirstRequest= () => {useEffect(() => {fetchData()console.log('first axios request') }, [])return <h2className="text-center">first request</h2>}exportdefault FirstRequest
Headers
We need to provide headers for POST and PATCH request. Some times in some apis we also need to provide headers for GET request.
const { data } =awaitaxios(url, { headers: {// if we don't put this headers and accept json, we get a text instead of json Accept:'Application/json', },})
We can add global defaults to axios. That means every time we make a axios request, that functionality will be added. For example, we can add these defaults in one file and import them
We have created axios folder and inside that, we have a file global.js where all axios defaults go.
Then we need to import this file in main file App.js or index.js like this
App.js or index.js
import'./axios/global'
Now we can use axios in the component file as ususal
GlobalInstance.js
import { useEffect } from'react'import axios from'axios'constproductsUrl='https://course-api.com/react-store-products'constrandomUserUrl='https://randomuser.me/api'constGlobalInstance= () => {constfetchData=async () => {try {/* both resp1 and resp2 will have request headers - application/json because of global settings done above */constresp1=awaitaxios(productsUrl) constresp2=awaitaxios(randomUserUrl)console.log(resp1)console.log(resp2) } catch (error) {console.log(error.response) } }useEffect(() => {fetchData() }, [])return <h2className="text-center">global instance</h2>}exportdefault GlobalInstance
both resp1 and resp2 will have request headers - application/json because of global settings of axios. We might not need this setting to one of the individual axios request sometimes, so let's see how to solve that using custom instance
Custom Instance
Here instead of global instance we use custom instance where we can create axios functions that have some defaults and we can use it where we want
axios/custom.js
import axios from'axios'constauthFetch=axios.create({ baseURL:'https://course-api.com',// this would be the root url headers: { Accept:'application/json', },})exportdefault authFetch
CustomInstance.js
import axios from'axios'import { useEffect } from'react'import authFetch from'../axios/custom'constrandomUserUrl='https://randomuser.me/api'constCustomInstance= () => {constfetchData=async () => {try {// the full url will be baseURL + this one = https://course-api.com/react-store-productsconstresp1=awaitauthFetch('/react-store-products') // this req has accept : application/json only and no textconstresp2=awaitaxios(randomUserUrl) // this is normal axios request } catch (error) {} }useEffect(() => {fetchData() }, [])return <h2className="text-center">custom instance</h2>}exportdefault CustomInstance
The below request has application/json
// this req has accept : application/json only and no textconstresp1=awaitauthFetch('/react-store-products')
The below second request is a normal axios request so it has both application/json and text
// this is a normal axios req that doesn't have any defaultsconstresp2=awaitaxios(randomUserUrl)
Interceptors
These are the axios functions that can be called before the request is sent and/or after getting the response.
Interceptors make more sense when we have complex applications for example if we have authentication in a big app. This is just an intro to interceptors and we can take a look later in projects as and when we need (I'll update this notes with more info as I come across it)
We will use CustomImplementation of axios and not global one in our example. We could also use Global ones, just fyi.
Component that uses interceptor that is used in App.js
Component that uses Interceptor
import { useEffect } from'react'import authFetch from'../axios/interceptor'consturl='https://course-api.com/react-store-products'constInterceptors= () => {constfetchData=async () => {try {constresp=awaitauthFetch('/react-store-products') // we already have first half of url as baseURL in authFetchconsole.log(resp) } catch (error) {} }useEffect(() => {fetchData() }, [])return <h2className="text-center">interceptors</h2>}exportdefault Interceptors
The request and response interceptors in authFetch
axios/interceptor.js
import axios from'axios'constauthFetch=axios.create({ baseURL:'https://course-api.com',// Lets put the below in interceptor// headers: {// Accept: 'application/json',// },})// REQUEST INTERCEPTORauthFetch.interceptors.request.use( (request) => {// we can see in network tab if accept is set to 'application/json'request.headers.common['Accept'] ='application/json'console.log('Request sent')return request // we always need to return the request from interceptor }, (error) => {returnPromise.reject(error) })// RESPONSE INTERCEPTORauthFetch.interceptors.response.use( (response) => {console.log('Response recieved')return response }, (error) => {returnconsole.log(error.response) })exportdefault authFetch
Now where this interceptors comes in handy? We can think of Authentication as one use-case.
Let's say if we get some type of response from backend, it will hit response interceptor. If the user is not logged in, then we get the 401 which can be caught in this response interceptor and we can log out the user immediately and set the state accordingly.
// RESPONSE INTERCEPTORauthFetch.interceptors.response.use( (response) => {console.log('Response recieved')return response }, (error) => {console.log(error.response)// for authentication this will be 401, but since we are// changing url for now it is 404, but behaviour would be sameif (error.response.status ===404) {// do something - we will generally update the state and may be logout the userconsole.log('Not found') }returnPromise.reject(error) })