본 글은 노마더 코더의 실전형 리액트 Hooks 10개 강의를 들으며 작성한 글입니다.
useAxios
이번에 주식 시세 프로젝트를 하면서 axios로 API를 호출해야 할 일이 생겼는데,
어떻게 API 호출을 좀 더 깔끔하게 할 수 없을까? 고민하다가 노마드코더에서 Hooks 강의를 들을 때
보았던 useAxios를 사용해볼 수 없을까 싶어서 정리할 겸 작성한다.
import React from "react";
import ReactDOM from "react-dom";
import useAxios from "./useAxios";
const App = () => {
const { refetch, loading, data, error } = useAxios({
url: "API 호출 주소"
});
return (
<div className="All">
<h1>{data && data.status}</h1>
<h2>{loading && "loading"}</h2>
<button onClick={refetch}>refetch</button>
</div>
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
App.jsx
- refetch : 재로딩 함수
- loading : 로딩 여부 true/false
- data : 로딩 후 들어온 데이터
- error : 로딩 후 들어온 에러
App.jsx에서는 useAxios를 import하여 option으로 API를 호출하는 URL을 넘겨준다.
<h1>{data && data.status}</h1>
<h2>{loading && "loading"}</h2>
위에서는 특이하게 작성된 부분이 있는데 data가 있다면(=true) data.status를 표시하고
loading이 true라면 loading이라는 글자를 표시하도록 && 연산자를 사용하여 작성하였다.
![]() |
![]() |
data가 존재하면 200이라는 request의 상태가 나오고,
refetch 버튼을 누르면 loading이라는 글자가 나오면서 API 호출 함수를 다시 호출하여 데이터를 다시 가져온다.
import defaultAxios from "axios";
import { useState, useEffect } from "react";
const useAxios = (opts, axiosInstance = defaultAxios) => {
const [state, setState] = useState({
loading: true,
error: null,
data: null
});
const [trigger, setTrigger] = useState(0);
const refetch = () => {
setState({
...state,
loading: true
});
setTrigger(Date.now());
};
useEffect(() => {
if (!opts.url) {
return;
}
axiosInstance(opts)
.then((data) => {
setState({
...state,
loading: false,
data
});
})
.catch((error) => {
setState({
...state,
loading: false,
error
});
});
}, [trigger]);
return { ...state, refetch };
};
export default useAxios;
useAxios.js
useAxios는 크게 3가지 부분으로 나눌 수 있는데 useState, trigger & refetch, useEffect로 구분한다.
const [state, setState] = useState({
loading: true,
error: null,
data: null
});
useState에서는 API의 loading 상태와 error와 data를 정의한다.
import defaultAxios from "axios";
import { useState, useEffect } from "react";
const useAxios = (opts, axiosInstance = defaultAxios) => {
...
useEffect(() => {
if (!opts.url) {
return;
}
axiosInstance(opts)
.then((data) => {
setState({
...state,
loading: false,
data
});
})
.catch((error) => {
setState({
...state,
loading: false,
error
});
});
}, [trigger]);
return { ...state, refetch };
};
useEffect에서는 opt과 axiosInstance를 파라미터로 받아
option(opt)에 url 속성을 호출해 받은 data를 state에 세팅하는 역할을 한다.
만약 data를 받는데 실패했다면 catch 문을 통해 data 대신 error를 세팅해주고 return한다.
이 useEffect문은 최초 로딩 시, 그리고 trigger가 바뀔 때 작동하는데
trigger는 refetch를 위해 선언된 state로 trigger를 변화시켜 useEffect를 작동하게 만든다.
const [trigger, setTrigger] = useState(0);
const refetch = () => {
setState({
...state,
loading: true
});
setTrigger(Date.now());
};
useEffect를 실행하기 위해 trigger라는 상태를 선언해주고,
refetch라는 함수 내에 setTrigger 함수를 선언해 refetch 함수 작동 시 trigger를 변경할 수 있게 만든다.
즉, refetch 호출 -> setTrigger로 trigger 상태 업데이트 -> useEffect 작동 -> API 호출과 같은 과정으로 refetch된다.
'Frontend > React' 카테고리의 다른 글
무한스크롤 컴포넌트 구현하기 -1- (0) | 2023.04.25 |
---|---|
프론트엔드에서의 TDD (0) | 2023.04.08 |
[React] Hook (0) | 2022.01.11 |
[React] 6. React Router (0) | 2021.11.25 |
[React] 5. Effect (0) | 2021.11.24 |