はじめに
ReactでHTTPクライアントとしてよく選択されるものにaxios
があります。
今回はそのaxiosに備わる機能、Axios Instance
についての注意とその対策法について紹介したいと思います。
その前に、件のAxios Instance
はどういうものかを一応簡単に解説します。
例えば以下のような設定をした時。
const customAxiosInstance = axios.create({
baseURL: 'https://some-domain.com/api/',
timeout: 1000,
headers: {
Authorization: `Bearer ${localStorage.getItem("token")}`,
}
});
このcustomAxiosInstance
インスタンスを使用することで、baseURL
・timeout
・headers
を指定した状態でHTTPリクエストを送ることができます。
await customAxiosInstance.get("/users");
// リクエストを送る時に以下と同等になる!
// const response = await axios.get("https://some-domain.com/api/users", {
// timeout: 1000,
// headers: {
// Authorization: `Bearer *******token***********`,
// },
// });
問題
問題となるのは、Axios Instance
でtokenなどを管理している時です。
例えばlocalStorageに保存しているtokenをAxios Instance
で使用している場合。
非ログインの状態でサイトにアクセスした時、
const customAxiosInstance = axios.create({
baseURL: "https://some-domain.com/api/",
headers: {
Authorization: `Bearer null`,
},
});
この時、非ログインなので当然tokenはnullになります。
ここまではいいのですが、ここでユーザーがログインをしたとします。
そうするとtokenが発行され、localStorageに保存されるわけですが...
このcustomAxiosInstance
は当然ですが更新されず、従ってtokenはnullのままです。
バックエンド等との通信もうまくいかないことになります。
また、この現象はおそらくウィンドウの再リロードでしか解決できず(間違っていたらすみません🙇🏻♂️)、
ログイン、ログアウト時にwindow.location.reload()
を実行というような無理矢理な方法をとらなければいけません。
結論としては、ログイン、非ログインなどユーザーの状態によって変動する値をリクエストに含めたい場合、
axiosの別の機能、すなわちInterceptors
を使用しましょう。
解決方法
Interceptors
は、リクエストの前後に任意の操作を挟み込める機能です。
これを使用した場合、先ほどのcustomAxiosInstance
は以下のようになります。
※これはミニマムであり、型やLintエラーが出る場合がありますが適宜修正してください🙏
const customAxiosInstance = axios.create({
baseURL: 'https://some-domain.com/api/',
timeout: 1000,
});
const authRequestInterceptor = (config: InternalAxiosRequestConfig) => {
const token = localStorage.getItem("token");
if (token !== null) {
// tokenがnullでない時、headerにAuthorizationを追加
config.headers.Authorization = `Bearer ${token}`;
}
return config;
};
// リクエストの前に、authRequestInterceptorの処理をする宣言
coustomAxiosInstance.interceptors.request.use(authRequestInterceptor);
こうすることで、axios.create
の恩恵を受けつつ、tokenなどの状態が変わるようなパラメーターも問題なくリクエストに含めることができるようになります。
おわりに
最後までお読みいただきありがとうございました!
修正や違う方法の提案等あれば是非是非コメントにお願いします😃
参考サイト