Axios & Custom Hook를 활용해보자 📡

Seokho·2022년 6월 17일
7

Westagram Project

목록 보기
3/4

Axios를 사용해보자!

이전까지 항상 fetch를 사용했습니다. 사용했던 이유는 사실 api통신을 처음 접한 방식이 fetch였고, 친숙했기 때문입니다. 그러다 F&F인턴 당시 axios를 알게 되었고 실제 현업에서는 axios를 선호할뿐만 아니라 React를 사용하는 회사는 보통 axios를 사용한다는 것을 알게되었습니다. 이후 프로젝트를 시작하면 axios를 경험해야지 라는 생각을 해왔는데, 이번 기회에 Custom Hooks를 사용해보면서 함께 사용해봤습니다. 그럼 Fetch와 Axios에 대해서 알아보겠습니다!

Axios와 Fetch의 등장배경

기존 Web에서 어떤 리소스를 비동기로 요청하기 위해서 XHR(XML HTTP Request)객체를 사용했어야 했는데, XHR은 잘 디자인되어 있는 API가 아닙니다. 요청의 상태나 변경을 구독하려면 Event를 등록해서 변경사항을 받아야 했었고 요청의 성공과 실패 여부, 상태에 따라 처리하는 로직이 들어가기 좋지 않았습니다.
이를 보완하기 위해 HTTP 요청에 최적화 되어 있고 상태도 잘 추상화 되어있는 api들이 생겨나기 시작했습니다.
대표적으로 Axios와 Fetch가 그 예입니다.

Axios

Axios는 Promise based HTTP client for the browser and node.js
즉, node.js와 브라우저를 위한 HTTP 통신 라이브러리 입니다.
비동기로 HTTP 통신을 가능하게 해주고 return을 promise 객체로 해주기 때문에 response 데이터를 다루기도 쉽고 좋습니다. React를 사용하는 사람들은 fetch보다 axios를 선호하는 편입니다.

Axios의 post method 구현

axios({
  method: 'post',
  url: '/user/12345',
  data: {
    firstName: 'Yongseong',
    lastName: 'Kim'
  }
});

장점

  • response timeout 처리 방법이 있다. (fetch에 존재하지 않음)
  • promise 기반으로 다루기 쉬움
  • 크로스 브라우징에 신경을 많이 썼기에 브라우저 호환성이 뛰어나다. (현업에서 사용하는 가장 큰 장점이자 이유)

단점

  • 모듈 설치를 해줘야함

Fetch

fetch는 ES6부터 Javascript의 내장 라이브러리로 등장했습니다.
promise 기반으로 만들어졌기 때문에 axios와 마찬가지로 데이터를 다루는데 용이하며, 내장 라이브러리라는 장점으로 편리합니다. 또한 코드도 간다합니다.

//fetch

const url ='http://localhost3000/test`
const option ={
   method:'POST',
   header:{
     'Accept':'application/json',
     'Content-Type':'application/json';charset=UTP-8'
  },
  body:JSON.stringify({
  	name:'sewon',
    	age:20
  })

  fetch(url,options)
  	.then(response => console.log(response))

장점

  • Javascript(ES6) 내장 라이브러리이기에 별도의 import 필요 없음
  • 내장 라이브러리이기에 사용하는 프레임워크가 안정적이지 않을 때 사용하기 좋음
  • promise 기반으로 다루기가 쉬움

단점

  • 기능이 부족함
  • internet explorer의 경우 fetch를 지원하지 않는 버전도 존재(브라우저 호환성이 상대적으로 떨어짐)

결론

추후 프로젝트 및 현업에서도 axios를 사용할 예정입니다. 아직 경험이 부족하기에 axios만의 특별한 장점을 피부로 와닿을정도로 느끼진 못했지만, 현업에서 fetch보다 axios를 선호한다는 것. 이것만으로도 구직자 입장에서는 납득할만한 이유가 됩니다.
또한, 더 글을 쓰며 더 학습하다보니 Axios가 크로스 브라우징에 신경을 많이 쓴 모듈인것을 많은 개발자분들이 느끼고 있다고 하고, 기능 또한 우수하다는 리뷰가 많습니다. 전체적으로 fetch의 상위 호환인 것 같습니다.

Custom Hooks

면접용으로 학습하다 보면 React 파트에서 필수로 알게되는 Custom Hooks 입니다. 반복되는 코드를 재사용할 수 있는 방식으로 상당히 유용하면서 실용적입니다.

Custom Hooks를 사용하는 이유

커스텀 훅의 핵심 키워드는 반복되는 로직 입니다. 반복되는 로직. 즉, 재사용을 의미 합니다. 코드와 로직의 반복을 최소화하고 재사용성을 높이기 위해 사용합니다. 또한, 변경사항이 있을 시 당연히 커스텀 훅에서만 변경하면 되기 때문에 수정하기도 상당히 효율적입니다.

  • 현업에서는 필수로 사용한다기 보다는 개발자 혹은 팀의 필요에 따라 달라진다고 합니다.

Code 예시

커스텁 훅을 작성 시 항상 use로 시작해야 합니다.
예를 들면 useInput, useFetch 처럼. 이후 어려운 것은 없습니다.
평소 리액트에서 컴포넌트를 만드는 것과 같이 만들면 됩니다. 아래의 코드를 보면 useFetch라는 커스텀훅을 만들고 있습니다.

import { useState } from 'react';

const useFetch = (initalUrl: string) => {
	const [url, setUrl] = useState(initalUrl);
    
    return [url, setUrl]
};

export default useFetch;

커스텀 훅이 만들어졌습니다. 일반 컴포넌트를 만들 때와 비슷한 구성을 가지고 있습니다. 커스텀 훅이지만 useState 혹은 useEffect를 자주 함께 사용합니다. 물론 다른 내장 훅들과 함께 사용가능하지만, 일반적으로 useState와 useEffect를 가장 빈번하게 사용됩니다.
또한 return을 JSX가 아닌 배열로 valus와 setValue로 합니다.

이제 axios를 용해 좀 더 깊게 알아보겠습니다.

import {useState, useEffect} from 'react';
import axios from 'axios';

const useFetch = (initalUrl: string) => {
  const [url, setUrl] = useState(initalUrl);
  const [value, setValue] = useState('');
  
  useEffect(() => {
    fetchData();
  }, [url]);
  
  const fetchData = () => axios.get(url).then(({data}) => setValue(data));
  
  return [value]
}

export dafault useFetch;
  1. initialUrl은 useState의 url이 넘겨 받습니다.
  2. useEffect가 실행됩니다.
  3. useEffect안에 존재하는 fetchData가 실행되고, 비동기식으로 value는 data를 받습니다.

이게 전체적인 과정입니다.
이제 사용하는 방법을 알아보겠습니다. value를 받아오는 대로 JSX에 value가 표시 됩니다.

import useFetch from '../../useFetch.tsx'

const App = () => {
  const [value] = useFetch('/api/something');
  
  return <div>{value}</div>;
}

export default App;

결론

  1. 커스텀 훅은 사용 시 앞에 use를 필수로 붙어야 함
  2. 커스텀 훅도 useState와 같은 내장 훅을 사용 가능
  3. 커스텀 훅은 코드와 로직의 중복을 줄이고 재사용성을 높여 효율적인 관리를 위해 사용함
  4. 커스텀 훅은 기본 컴포넌트를 만들 때와 비슷하고, JSX가 아닌 배열 혹은 오브젝트를 return 함
  5. 커스텀 훅을 사용하는 방법은 useState와 비슷함

프로젝트에서 Custom Hooks와 Axios

위에서 학습한 내용을 바탕으로 axios와 커스텀 훅을 사용했습니다. 이번 프로젝트에서는 사실 백엔드와 함께 진행하지 않았기 때문에 직접 mock data를 만들어 통신했고, 반복되는 로직은 아니었지만 경험하기 위해 커스텀 훅을 사용했습니다.

import { useState, useEffect } from 'react';
import axios from 'axios';
import { IgetData, IResponse } from '../Type/Interface';

const useGetData = (url: IgetData) => {
  const [data, setData] = useState<IResponse[]>();
  const [isLoading, setIsLoading] = useState<boolean>(true);
  const [error, setError] = useState<string>('');

  useEffect(() => {
    const fetchData = async () => {
      try {
        await axios(url)
          .then(res => {
            setData(res.data);
          })
          .finally(() => {
            setIsLoading(false);
          });
      } catch (err: any) {
        setError(err);
        alert(err);
      }
    };
    if (isLoading) {
      fetchData();
    }
  }, [url]);

  return { data, error, isLoading };
};

export default useGetData;

위의 내용에 더 추가해, async와 await로 비동기 통신을 순차적으로 실행할 수 있게 했습니다. 또한, try & catch를 사용해 프로그램 실행 시 문제를 대응 할 수 있게 예외처리를 진행했습니다.

profile
같이의 가치를 소중하게 생각하는, 프론트엔드 개발자 이석호 입니다.

0개의 댓글