React 애플리케이션은 구성 요소에서 빌드됩니다. 기본 제공이든 사용자 지정이든 관계없이 구성 요소는 Hooks에서 빌드됩니다. 다른 사람이 만든 사용자 정의 Hook을 자주 사용하겠지만 가끔 직접 작성할 수도 있습니다.
다음 명명 규칙을 따라야 합니다.
React 컴포넌트 이름은 StatusBar
와 SaveButton
같이 대문자로 시작해야 합니다. React 구성 요소는 또한 JSX 조각과 같이 React가 표시하는 방법을 알고 있는 것을 반환해야 합니다.
Hook 이름은 useState
(built-in) 또는 useOnlineStatus
(custom, like earlier on the page)와 같이 use 다음에 대문자로 시작해야 합니다. Hooks는 임의의 값을 반환할 수 있습니다.
useAxios를 사용 하기 전 axios instance를 설정한다면 백엔드와 통신 시 반복되는 작업을 줄일 수 있습니다.(ex. access token 전달, withCredentials: true 등등)
사용자 지정 config로 새로운 Axios 인스턴스를 만들수 있습니다.
axios.create([config])
config 설정은 공식문서에서 확인 가능합니다.
const instance = axios.create({
baseURL: 'https://some-domain.com/api/',
timeout: 1000,
headers: {'X-Custom-Header': 'foobar'}
});
// src/lib/api/index.ts
import axios from "axios";
import { store } from "../../app/store";
export const axiosInstance = axios.create({
baseURL: "https://some-domain.com/api/",
timeout: 60000,
headers: {'X-Custom-Header': 'foobar'},
withCredentials: true,
});
axiosInstance.interceptors.request.use(
(config) => {
const accessToken = store.getState().accessTokenValue.accessTokenValue;
// console.log(accessToken);
if (accessToken) {
config.headers["Authorization"] = accessToken;
}
console.log("axios config : ", config);
return config;
},
(error) => {
console.log("axios config : ", error);
return Promise.reject(error);
}
);
axiosInstance.interceptors.response.use(
(response) => {
console.log("axios config : ", response);
return response;
},
(error) => {
// 이 부분에서 access token, refresh token 갱신 가능합니다.
console.log("axios config : ", error);
return Promise.reject(error);
}
);
import { useState, useEffect, useRef } from "react";
import { AxiosError, AxiosRequestConfig, AxiosResponse } from "axios";
import { axiosInstance } from "../../lib/api/index";
export const useAxios = <D = any>(axiosParams: AxiosRequestConfig<D>) => {
const [response, setResponse] = useState<AxiosResponse | null | any>(null);
const [error, setError] = useState<AxiosError | any | unknown>(null);
const [loading, setLoading] = useState(true);
const [trigger, setTrigger] = useState(0);
const controllerRef = useRef(new AbortController());
const refetch = () => {
setResponse([...response]);
setError(error);
setLoading(true);
setTrigger(Date.now());
};
const axiosData = async (params: AxiosRequestConfig<D>) => {
try {
const result = await axiosInstance.request({
...params,
signal: controllerRef.current.signal,
});
setResponse(result?.data?.data);
} catch (error: AxiosError | any | unknown) {
setError(error);
} finally {
setLoading(false);
}
};
useEffect(() => {
axiosData(axiosParams);
}, [trigger]);
return {
response,
error,
loading,
setResponse,
refetch,
};
};
// App.tsx
const App () => {
const {response, error, loading, refetch} = useAxios({
url: "https://some-domain.com/api/",
method: "GET", // 생략 가능\
})
return (
<div>
<button type="button" onClick={refetch} />
{loading ? (
<div>loading...</div>
) : error ? (
<div>error</div>
) : (
<div>{response}</div>
)}
</div>
reference
리액트 공식문서
axios 공식문서
https://blog.sreejit.dev/custom-axios-hook-useaxios-in-typescript-react
https://medium.com/stackanatomy/integrating-axios-with-react-hooks-f3caccee83b3