gh-page๋ก ๊ฒฐ๊ณผ๋ฌผ ํ์ธํ๊ธฐ
changed ๋ฅผ ๋๋ฅด๋ฉด redux-devTools๋ก ํด๋น ์ก์ ๋ค์ ๊ฐ์งํ๊ณ , ๋ณํ๋ state ๊ฐ์ ํ์ธํ ์ ์์ต๋๋ค.
- ํด๋์คํ ์ปดํฌ๋ํธ๋ฅผ ํจ์ํ ์ปดํฌ๋ํธ๋ก ๋ณ๊ฒฝ โ๏ธ
- ๋ฆฌ๋์ค์ฌ๊ฐ๋ฅผ ํตํ ๋น๋๊ธฐ์ฒ๋ฆฌ โ๏ธ
- ์คํ ์ด๋ฅผ ํตํ ์ํ๊ด๋ฆฌ โ๏ธ
๐ ์ธํผ๋ํฐ ์คํฌ๋กค ๊ธฐ๋ฅ ์ถ๊ฐ ์ฌ๋ถ ํ์ โ๏ธ
๐ url์ ํตํด ๋๊ฒจ๋ฐ๋ API๋ฅผ ์ด๋ป๊ฒ ๋๋ ์ค ์ ์์์ง โ
- ํ์ ์คํฌ๋ฆฝํธ ์ ์ฉ
์ธ๋ถ URL : https://yts.mx/api/v2/list_movies.json
ํ์ํ ํฌ๋กฌ ํ์ฅ ํ๋ก๊ทธ๋จ: JSON VIEWR
์ถ์ฒ: ๋์ฝ์ค์ ReactJS๋ก ์ํ ์น ์๋น์ค ๋ง๋ค๊ธฐ
์ฐ๋ฆฌ๊ฐ ๋ถ๋ฌ์ค๊ณ ์ ํ๋ ์คํ API์ ๋ฐ์ดํฐ ํ์์ ๋ค์๊ณผ ๊ฐ๋ค.
์ฒซ ๋ฒ์งธ๋ก ์คํ ๋ฐ์ดํฐ API๋ฅผ axios ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅด ์ฌ์ฉํ์ฌ ๋ถ๋ฌ์ฌ ๋ ์ค์ํ ์ ์ ๋ฐ์ดํฐ๊ฐ ์ด๋ค ๊ตฌ์กฐ๋ก ๋ค์ด ์๋ ์ง๋ฅผ ํ์ธํ๋ ๊ฒ์ด๋ค.
const getMovies = async () => {
const response = await axios.get('https://yts-proxy.now.sh/list_movies.json?limit=30&&sort_by=download_count');
console.log(response);
};
ํด๋น api ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ ์ฝ์๋ก๊ทธ๋ก ์ฐ์ผ๋ฉด ๋ค์๊ณผ ๊ฐ์ ๊ฒฐ๊ณผ๊ฐ์ ์ป์ ์ ์๋ค. Object ๊ฐ์ฒด ์์ ํ๋กํผํฐ ํ์์ผ๋ก ๋ค์ด์๋ค.
์ฐ๋ฆฌ๊ฐ ์ ๊ทผํด์ผ ํ๋ movies ํ๋กํผํฐ๋ ๊ฒฐ๊ณผ์ ์ผ๋ก ๋ฐ์์ค๋ data.data.movies ์์ ๋ค์ด์๋ ๋ฐฐ์ด๋ก ์ด๋ฃจ์ด์ง ๊ฐ์ฒด๋ค์ด๋ค.
[0] : {id : 8462 , title, genres, ...}
๊ทธ์ ๋ง์ถฐ ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ค๊ธฐ ์ํด์๋ data.data.movies.id, ... ์ ๊ฐ์ด ๋ถ๋ฌ์์ผ ํ๋ฏ๋ก ๊ตฌ์กฐ ๋ถํด ํ ๋น ๋ฌธ๋ฒ์ ํตํด movies ํ๋กํผํฐ ์์ ๋ค์ด์๋ ๋ด์ฉ์ movies ๋ณ์์ ๋ด์ ๊ฐ์ ธ์จ๋ค.
const {data: {data: { movies },},} = await axios.get('https://yts-proxy.now.sh/list_movies.json?limit=30&&sort_by=download_count');
๊ตฌ์กฐ๋ถํดํ ๋น์ ํตํด ์ป์ด์จ movies ๊ฐ์ฒด๋ฅผ ์ฐ์ผ๋ฉด ์ฐ๋ฆฌ๊ฐ ์ป๊ณ ์ ํ๋ ๋ฐฐ์ด ํ์์ ๋ฐ์ดํฐ๋ฅผ ์ป์ ์ ์๊ฒ๋๋ค.
[0] : {id : 8462 , title: ..., genres: ..., ...}
[1] : {id : 8463 , title: ..., genres: ..., ...}
[2] : {id : 8464 , title: ..., genres: ..., ...}
[3] : {id : 8465 , title: ..., genres: ..., ...}
[4] : {id : 8466 , title: ..., genres: ..., ...}
์ด ๋ฐ์ดํฐ๋ฅผ ๊ธฐ์กด reducer์์ intialState๋ก ๊ด๋ฆฌํ๋ movies : [] ์ concat ํด์ฃผ๋ฉด ๋ฆฌ๋์๋ฅผ ์ฌ์ฉํ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ค๋ ์ฒ๋ฆฌ๋ฅผ ํ ์ ์๋ค.
- ์ฒซ ๋ฒ์งธ๋ก, ํ๋ฉด์ ๋ณด์ฌ์ฃผ๋ view ๋จ์์ useEffect()๋ฅผ ํตํด ์ํฉ์ ๊ฐ์งํ๋ค. ์๋ฌด๊ฒ๋ ์๋ ์ํ์ผ ๋, dispatch๋ฅผ ํตํด LOAD_MOVIES_REQUEST ์ก์ ์ ์คํํ๋ค.
// useEffect์ ์กฐ๊ฑด๋ฌธ์ ํตํด ํน์ ํ ์ํฉ์ ์ ํด์ฃผ์ง ์์์ผ๋ฏ๋ก, ํด๋น ์ดํ๋ฆฌ์ผ์ด์
์ด ๋ ๋๋ง๋ ๋ ์คํ์ํจ๋ค.
useEffect(() => {
dispatch({
type: LOAD_MOVIES_REQUEST,
});
}, [dispatch]);
- sagas/movies ์์ LOAD_MOVIES_REQUEST ์ ๊ฐ์งํ๋ ํจ์ watchLoadMovies()๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ค๋ ํจ์ loadMovies()๋ฅผ ์คํํ๋ค.
function* watchLoadMovies() {
yield takeLatest(LOAD_MOVIES_REQUEST, loadMovies);
}
export default function* movieSaga() {
yield all([fork(watchLoadMovies)]);
}
- loadMovies()๋ฅผ ์คํํ์ ๋ ์ค์ ์์ ์ ์งํํ๋ loadMoviesAPI()๋ฅผ ์คํํ ํ ๊ฒฐ๊ณผ๊ฐ์ result์ ๋ด๋๋ค.
async function loadMoviesAPI() {
try {
const {
data: {
data: { movies },
},
} = await axios.get('https://yts-proxy.now.sh/list_movies.json?limit=10&&sort_by=download_count');
// ์ฌ๊ธฐ์ ํ์ธ
console.log(`movies ๊ฐ์ ธ์์ ๊ตฌ์กฐ๋ถํดํ ๋น์ผ๋ก ๋ด๊ธฐ`);
console.log(movies);
return movies;
} catch (err) {
console.error(err);
return;
}
}
function* loadMovies() {
const result = yield call(loadMoviesAPI); // loadMoviesAPI ํจ์ ํธ์ถ์ ์ํด return ๋ movies ๊ฐ์ฒด
// ์ฌ๊ธฐ์ ์ ๋ถ๋ฌ์๋์ง ํ์ธ
console.log('๋ฆฌํด๋ result ์ถ๋ ฅ :');
console.log(result);
- ์ป์ด์ค๋ ๋ฐ์ดํฐ ์ฒ๋ฆฌ์ ๋ฐ๋ผ LOAD_MOVIES_SUCCESS ๋๋ LOAD_MOVIES_FAILURE๋ฅผ ๋ฐ์์ํค๊ณ ๊ทธ์ ํจ๊ป data๋ฅผ ์ ๋ฌํ๋ค. (์๋ฌ์ผ ๊ฒฝ์ฐ error๋ฅผ ์ ๋ฌ)
function* loadMovies() {
const result = yield call(loadMoviesAPI); // loadMoviesAPI ํจ์ ํธ์ถ์ ์ํด return ๋ movies ๊ฐ์ฒด
// ์ฌ๊ธฐ์ ์ ๋ถ๋ฌ์๋์ง ํ์ธ
console.log('๋ฆฌํด๋ result ์ถ๋ ฅ :');
console.log(result);
try {
console.log('saga loadMovies start!');
yield put({
type: LOAD_MOVIES_SUCCESS,
data: result,
});
} catch (err) {
console.error(err);
yield put({
type: LOAD_MOVIES_FAILURE,
error: err.response.data,
});
}
}
- ๋ฆฌ๋์์์ ์ฌ๊ฐ์์ ์ ๋ฌ๋ฐ์ ์ก์ ๊ณผ, ์ก์ ์ ๋ด๊ธด ๋ฐ์ดํฐ๋ฅผ ์คํํ๋ค.
const movies = (state = initialState, action) =>
produce(state, (draft) => {
switch (action.type) {
case LOAD_MOVIES_REQUEST: {
draft.loadMovieLoading = true;
draft.loadMovieDone = false;
break;
}
case LOAD_MOVIES_SUCCESS: {
draft.movies = draft.movies.concat(action.data);
// action.data ์๋ ์ฌ๊ฐ์์ ๋๊ฒจ์ค result ๊ฐ์ด ๋ด๊ฒจ์๋ค.
draft.isLoading = false;
// ๋ฐ์ดํฐ๋ฅผ ์ฑ๊ณต์ ์ผ๋ก ๋๊ฒจ๋ฐ์ ์, initialStae์์ ๊ด๋ฆฌํ๋ isLoading์ false ๋ก ๋ฐ๊ฟ์ค๋ค. ์ด ์กฐ๊ฑด์ ํตํด movies๋ฅผ ๋งคํํ ์ ์๊ฒ ๋๋ค.
draft.loadMovieDone = true;
break;
}
case LOAD_MOVIES_FAILURE: {
draft.loadMovieError = action.error;
break;
}
default:
return state;
}
});
- virtual DOM์ด ๋ฐ๋ state๋ฅผ ๊ฐ์งํ์ฌ ๋ฆฌ๋ ๋๋งํ๋ค.
return (
<section className="container">
{isLoading ? (
<div>๋ก๋ฉ์ค..</div>
) : (
<div className="movies">
{movies.map((movie) => (
<Movie
key={movie.id}
id={movie.id}
year={movie.year}
title={movie.title}
summary={movie.summary}
poster={movie.medium_cover_image}
genres={movie.genres}
/>
))}
</div>
// <div>๋ก๋ฉ ์๋ฃ!</div>
)}
</section>
);
- redux-saga๋ฅผ ์ฒ๋ฆฌํ๋ ๊ณผ์ ์์ ๋๊ฒจ๋ฐ์ ๊ฒฐ๊ณผ๊ฐ์ ๊ทธ๋๋ก ์ ๋ฌํด์ผ ํ๋๋ฐ, ์๋ฒ์์ ๋ฐ์ ๊ฒ์ฒ๋ผ result.data๋ก ์ฒ๋ฆฌํ๋ฉด ๋ฆฌ๋์์์ concat ํ ๋ undefined ๊ฐ ๋ฐ ์ ์๋ค.
function* loadMovies() {
const result = yield call(loadMoviesAPI);
try {
yield put({
type: LOAD_MOVIES_SUCCESS,
data: result, // ์ฌ๊ธฐ์ result.data๋ก ์ฐ์ง ์๋๋ก ์ฃผ์ํ๋ค.
});
} catch (err) {
console.error(err);
yield put({
type: LOAD_MOVIES_FAILURE,
error: err.response.data,
});
}
}
- redux-saga๋ฅผ ํตํด ์ฒ๋ฆฌํ๋ฏ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ฌ ๋๊น์ง ๊ธฐ๋ค๋ ธ๋ค๊ฐ ๋ค์ ์์ ์ ์งํํ ์ ์๋๋ก js์ generator์ ๊ฐ๋ ์ ์ ์๊ณ ์์ด์ผ ํ๋ค.
์ฌ๊ฐ์์ data๋ฅผ ๋๊ฒจ์ฃผ์ง ์๊ณ , ์ก์ ํ์ ์ธ LOAD_MOVIES_SUCCESS๋ง ๋ณด๋ด์ฃผ๊ณ ๋ฆฌ๋์์์ ์์ ํจ์ getMovies()๋ฅผ ์ฒ๋ฆฌํ ๊ฒฝ์ฐ ๋ฐ์ดํฐ๋ฅผ ์ ๋๋ก ๋ฐ์์ค์ง ๋ชป ํ ์ฑ๋ก ๋๊ฒจ์ค ์ ์๋ค.
// getMovies()์ ๋ฐ๋ ํํ, ๋ฆฌ๋์ค-์ฌ๊ฐ ์ฒ๋ฆฌ๊ณผ์ ์ ๊ฑฐ์น๊ธฐ ๋๋ฌธ์ call() ํจ์๋ก loadMoviesAPI()๋ฅผ ์คํํ ํ ๋ฆฌํด๋ฐ์ movies๋ฅผ loadMovies() ํจ์์์ result๋ก ๋ฐ์์คฌ๋ค.
async function loadMoviesAPI() {
try {
const {
data: {
data: { movies },
},
} = await axios.get('https://yts-proxy.now.sh/list_movies.json?limit=10&&sort_by=download_count');
// ์ฌ๊ธฐ์ ํ์ธ
console.log(`movies ๊ฐ์ ธ์์ ๊ตฌ์กฐ๋ถํดํ ๋น์ผ๋ก ๋ด๊ธฐ`);
console.log(movies);
return movies;
} catch (err) {
console.error(err);
return;
}
}
์ธํผ๋ํฐ ์คํฌ๋กค์ ๊ตฌ๊ธ๋งํ๋ฉด ์ ๋ง ๋ค์ํ ์์ ๋ค์ ์ฐพ์๋ณผ ์ ์์ต๋๋ค. ์ธํผ๋ํฐ ์คํฌ๋กค์ด๋ ๊ฒฐ๊ตญ ์ด๊ธฐ ๋ ๋๋ง ์๋๋ฅผ ๋ํ๊ธฐ ์ํด์ ์ฒ์ ํ์ด์ง๋ฅผ ๋ ๋๋งํ ๋ ๋ณด์ฌ์ฃผ๋ ๊ฒ์๊ธ ๋๋ ์ด๋ฏธ์ง์ ๊ฐ์๋ฅผ ์ ํํ๊ณ , ํ์ ์ฌ์ฉ์์ ์๊ตฌ์ ๋ฐ๋ผ ์๋ฒ์์ ํด๋น ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐ๋ก ๋ถ๋ฌ์ค๋ ๋ฐฉ์์ ๋๋ค.
์ด์ ์ ์ ๊ฐ ํด์๋ ๋ฐฉ๋ฒ๋ค ์ฒ๋ผ ์ฌ์ฉ์๋ค์ ์ํด ์์ฑ๋ ๋ฐ์ดํฐ๋ฅผ LOAD_POSTS_REQUEST ์ ๊ฐ์ด ์๋ฒ์์ ๋ถ๋ฌ์ค๋ ๊ฒ์ ๋ณ ๋ฌธ์ ๊ฐ ๋์ง ์์์ง๋ง, OPEN API์์ ํด๋น ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ค๋ ๊ธฐ์ ์ ๊ตฌํํ๊ธฐ์๋ ์ ๋ง ๋ง๋งํ์ต๋๋ค.
axios.get('https://yts-proxy.now.sh/list_movies.json?limit=10&&sort_by=download_count')
์ ๊ฐ์ด https://...json? ๋ค์ ๋ถ๋ ๋ฌธ์์ด์, API ๋ฌธ์๊ฐ ์ ๊ณตํ๋ ์ฟผ๋ฆฌ ์์ฑ ๋ค์ ๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ์ ๊ณตํ๋ API๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
์ ์ ์ ๊ณต์ด DB ๊ด๋ จ์ด๊ธฐ ๋๋ฌธ์, limit ๋ผ๋ ์์ฑ์ ๋ณด๊ณ ์ฒ์์๋ limit=[1,10]์ ๊ฐ์ด ์ฟผ๋ฆฌ๋ฅผ ์ค์ ํด์ผ๊ฒ ๋ค๊ณ ์๊ฐํ์ต๋๋ค. limit์ ๊ฐ์ ์ด๊ธฐ์ ์ค์ ํ๊ณ , ํ์ state๋ฅผ ํตํด LOAD_MOVIES_POST ๋ฅผ ์คํํ ๋๋ง๋ค ํด๋น limit ์์ฑ๊ฐ์ ์ ๋ฐ์ดํธ ํ๊ณ ์ถ์์ง๋ง, ์ฟผ๋ฆฌ๋ฌธ์์ ์ ํจํ์ง ์์(?) API์์ ์ ๊ณตํ์ง ์๋ ๋ฐฉ๋ฒ์ด๋ผ ์ด๊น ๊ฐ์ธ limit=20 ์ผ๋ก ๋ฐ๋ณต๋์์ต๋๋ค.
๊ทธ๋ฌ๋ ์ค page ๋ผ๋ ์์ฑ์ ๋ฐ๊ฒฌํ๋๋ฐ, limit๋ก ์ ํํ ์ํ๋ฐ์ดํฐ๋ฅผ ํ์ด์ง ๋ณ๋ก ๊ฐ์ ธ์ฌ ์ ์์์ต๋๋ค. ๊ทธ๋์ ์ด ํ์ด์ง ๊ฐ์ useState๋ก ๊ด๋ฆฌํ์ฌ, ์ธํผ๋ํฐ ์คํฌ๋กค์ ํตํด LOAD_MOVIES_REQUEST๊ฐ ์คํ๋ ๋๋ง๋ค ์ด `page` ์์ฑ ๊ฐ์ ์ฌ๋ ค์ค ๋ค์ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๋๋ก ๊ตฌํํ์์ต๋๋ค.
axios.get(`https://yts-proxy.now.sh/list_movies.json?limit=10&&sort_by=download_count&page=${data}`);
์ด์ฒ๋ผ page=${data} ์ฟผ๋ฆฌ ๋ฌธ์ ํตํด, dispatch ์์ action๊ณผ ํจ๊ป data๋ก ๋ฐ์์ ์ ๋ฐ์ดํฐ๋ฅผ ๋ฅ๋์ ์ผ๋ก ๊ด๋ฆฌํ ์ ์์์ต๋๋ค.
์ถ๊ฐ์ ์ผ๋ก action.data๋ฅผ loadMoviesAPI์ ๋ณด๋ด์คฌ๋๋ฐ ์ฌ๊ธฐ์ ๋์ค๋ action.data๊ฐ ์ฐ๋ฆฌ๊ฐ ์ ๋ฐ์ดํธํ๊ณ ์ถ์ page์ state ๊ฐ์ ๋๋ค.
๐ sagas/movies.js
...
function* loadMovies(action) {
const result = yield call(loadMoviesAPI, action.data);
// action { type:LOAD_MOVIES_REQUEST , data: pageNumber} ์ด๋ฏ๋ก action.data ๋ฅผ ํตํด
// pageNumber์ ์ ๊ทผํ๊ณ ์ด data๋ฅผ loadMoviesAPI์ ๋๊ฒจ์ฃผ์์ต๋๋ค.
try {
yield put({
type: LOAD_MOVIES_SUCCESS,
data: result,
});
} catch (err) {
console.error(err);
yield put({
type: LOAD_MOVIES_FAILURE,
error: err.response.data,
});
}
}
useState๋ก ๊ด๋ฆฌํ page๋ฅผ ํฌํจํ ํ์ด์ง๋จ์ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
๐ pages/HomeChanged
...
const [pageNumber, setPageNumber] = useState(1);
const dispatch = useDispatch();
useEffect(() => {
dispatch({
type: LOAD_MOVIES_REQUEST,
data: pageNumber,
});
setPageNumber((pageNumber) => pageNumber + 1);
}, [dispatch]);
const handleScroll = () => {
const scrollHeight = document.documentElement.scrollHeight;
const scrollTop = document.documentElement.scrollTop;
const clientHeight = document.documentElement.clientHeight;
if (scrollTop + clientHeight >= scrollHeight) {
console.log(`pageNumber ์
๋ฐ์ดํธ ${pageNumber}`);
// ํ์ด์ง ๋์ ๋๋ฌํ๋ฉด ์ถ๊ฐ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์จ๋ค
dispatch({
type: LOAD_MOVIES_REQUEST,
data: pageNumber,
});
setPageNumber((pageNumber) => pageNumber + 1);
}
};
useEffect(() => {
// scroll event listener ๋ฑ๋ก
window.addEventListener('scroll', handleScroll);
return () => {
// scroll event listener ํด์
window.removeEventListener('scroll', handleScroll);
};
}, [pageNumber, dispatch]);
pageNumber์ ์ด๊ธฐ๊ฐ์ 1๋ก ์ฃผ์๊ณ , ์ฒ์ ์๋ฌด๊ฒ๋ ์๋ ์ํ์์ LOAD_MOVIES_REQUESt๋ฅผ ์คํํ ํ, pageNumber๋ฅผ ์ฌ๋ ค์ค๋๋ค. ๊ทธ๋ฌ๋ฉด axios ๋จ์์ ๋ค์ ํ์ด์ง์ limit=10 ์์ฑ๊ณผ ํจ๊ป ์ํ ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐ์ ์ผ๋ก ๊ฐ์ ธ์ฌ ๊ฒ์ ๋๋ค.
๐/sagas/movies
...
async function loadMoviesAPI(data) {
// 3. data ์์๋ action.data ์ฆ useState๋ก ๊ด๋ฆฌํ๋ pageNumber ๊ฐ ๋ค์ด์์ต๋๋ค.
// 4. ์ถ๊ฐ์ ์ผ๋ก ์์ฒญ์ด ์๊ธธ ๋๋ง๋ค 1, 2, 3, ... ์ฆ๊ฐํ๋ฉฐ ๋ฐ์ดํฐ๋ฅผ ํ์ด์ง ๋ณ๋ก ๋๋ ๋ถ๋ฌ์ฌ ์ ์์ต๋๋ค.
try {
const {
data: {
data: { movies },
},
} = await axios.get(`https://yts-proxy.now.sh/list_movies.json?limit=10&&sort_by=download_count&page=${data}`);
return movies;
} catch (err) {
console.error(err);
return;
}
}
function* loadMovies(action) {
const result = yield call(loadMoviesAPI, action.data);
// 1. action.data์๋ dispatch ์์ ์ก์
ํ์
๊ณผ ๊ฐ์ด ๋ณด๋ธ data, ์ฆ pageNumber ๊ฐ ๋ค์ด์์ต๋๋ค.
// 2. ์ด๋ฅผ call loadMoviesAPI๋ฅผ ํธ์ถํ๋ฉด์ ๊ฒฐ๊ณผ๊ฐ์ result์ ๋ด์ต๋๋ค.
try {
yield put({
type: LOAD_MOVIES_SUCCESS,
data: result,
});
} catch (err) {
console.error(err);
yield put({
type: LOAD_MOVIES_FAILURE,
error: err.response.data,
});
}
}
ํญ์ ๊ฐ์๋ง ๋ฐ๋ผํ๋ฉด์ ๊ณต๋ถ๋ฅผ ํ๊ธฐ ๋๋ฌธ์ ์๋ ค์ฃผ์ง ์๋ ๊ธฐ์ ์ ๋ํด ๋์ ํ๋ ๊ฒ์ด ๋๋ ต๊ณ ํ๋ค์์ต๋๋ค. ํ์ง๋ง ๊ตฌ๊ธ๋ง๊ณผ ํจ๊ป ์์ ์๋ฆฌ์์๋, ์๊ณ ์ผ์ด๋์๋, ์ด๋ํ๋ฉด์๋ ๊ณ ๋ฏผ์ ๊ณ์ํ๋ฉด์ '์ด๋ ๊ฒ ํด๋ณด๋ฉด ์ด๋จ๊น', '์ ๋ ๊ฒ ํด๋ณด๋ฉด ์ด๋จ๊น' ๋ฅผ ๋ฐ๋ณตํ๋๋ฐ, ๊ฒฐ๊ณผ์ ์ผ๋ก ๋ฐฐ์ ๋ ๋ด์ฉ์ ๋ฐํ์ผ๋ก ๋ฐ์ดํฐ ๋ ๋๋ง์ ์ฑ๊ณตํ ์ ์์์ต๋๋ค.
axios๋ฅผ ํตํด api์์ ๋ถ๋ฌ์จ ๋ฐ์ดํฐ๋ฅผ ๊ตฌ์กฐ๋ถํด ํ ๋น์ ํตํด ํ์ํ ๋ชจ์ต์ผ๋ก ๊ฐ์ ธ์ ๋ ๋๋งํ๋ ๋ถ๋ถ์ด ๋งค์ฐ ์ฌ๋ฐ์๊ณ , ๋ํ api์ ์ฟผ๋ฆฌ๋ฌธ์ ์ถ๊ฐํ์ฌ ์ํ๋ ํ์์ผ๋ก ๋ฐ๊ฟ ๊ฐ์ ธ์ค๋ ๊ณผ์ ์ด ํฅ๋ฏธ๋ก์ ์ต๋๋ค.