#1. Axios-hooks

1. Axios-hooks의 개념

1) Axiois-hooks란?

  • 서버 사이드 렌더링에 대한 지원이 내장된 axios를 위한 hook이다.
    • Axios 라이브러리(ajax 요청 라이브러리) 사용을 간소화 시켜준다

 

2) 특징

  • 한줄에 모든 기능을 사용할 수 있다.
  • SSR과 함께 사용하기 매우 간단하다.

 

2. Axios-hooks 사용하기

1) 설치

  • 다른 패키지 설치할 때와 같은 방법으로 설치한다.
yarn add axios-hooks
  • 상단에 아래 코드를 import 시켜준다.
import useAxios from 'axios-hooks';

 

2) 기본 사용 방법

const [{ data, loading, error }, refetch] = useAxios(url);
  • data: 응답결과로 수신된 json 결과 (응답에 성공한 데이터 속성)
  • loading: 로딩 여부를 나타내는 boolean 값 (요청이 진행 중이면 true, 그렇지 않으면 false 입니다.)
  • error: 에러가 존재할 경우 에러 정보를 내장하고 있는 객체
  • refetch: 요청을 다시 보내고자 할 경우 사용할 함수
  • url: 데이터를 요청할 url 주소 (path 파라미터 혹은 querystring을 포함하고 있어야 한다.)

 

3. CRUD에 따른 요청 방법

1) GET

  • params에 설정한 정보는 querystring 으로 전송된다.
const [{ data, loading, error }, refetch] = useAxios({ 
  url: '요청할 URL',
  method: 'GET',
  params: { key: value, key: value }
});

 

2) POST | PUT | DELETE

const [{ data, loading, error }, refetch] = useAxios({ 
  url: '요청할 URL',
  method: 'POST|PUT|DELETE',
  data: { key: value, key: value }
});

 

3) 메뉴얼 요청 (수동요청)

  • hook 기능을 사용하면 컴포넌트가 마운트됨과 동시에 ajax 요청이 전송된다.
  • 입력, 수정, 삭제, 조회 등의 기능은 사용자 이벤트가 발생했을 때 요청을 전송해야 하기 때문에 자동 전송되게 하지 않고 수동으로 전송할 수 잇는 메뉴얼 기능을 사용해야 한다.

 

- 메뉴얼 요청 설정

  • 뒤에 { manual: true }를 추가한다.
const [{ data, loading, error }, refetch] = useAxios({ 
  url: ...
  method: ...
}, { manual: true });

 

4) 메뉴얼 요청 전송하기

  • ajax를 재요청할 때는 refetch( ) 함수를 사용한다.

 

- 설정된 그대로 메뉴얼 요청 전송

refetch();

 

- GET 방식일 경우 요청 파라미터를 변경하여 전송

refetch({
  params: {key:value, key: value}
});

 

- PUT, POST, DELETE 방식일 경우 요청 파라미터를 변경하여 전송

refetch({
  data: {key:value, key: value}
});

 

4. 실습

- src/App.jsx

import React, { memo, useCallback, useEffect, useState } from 'react';
// useAxios 참조
import useAxios from 'axios-hooks';
// 커스텀 hook 참조
import useMounterRef from './hook/useMounterRef';

const App = () => {

  // ------------------------------------------------------- hook 정의 시작
  // useAxios로 데이터 호출
  const [{ data, loading, error }, refetch] = useAxios('http://localhost:3001/traffic_acc');
  // 연도에 따른 상태값 정의
  const [ year, setYear ] = useState('');
  // ------------------------------------------------------- hook 정의 끝


  // ------------------------------------------------------- 드롭다운 이벤트 시작
  // 드롭다운 선택 변경시 호출되는 이벤트
  const onSelectChagne = useCallback(e => {
    e.preventDefault();

    // 드롭다운의 입력값 가져온다.
    const current = e.target;
    const value = current[current.selectedIndex].value;

    setYear(value);
  }, []);

  // 이 컴포넌트가 화면에 마운트 되었는지를 확인
  const mountedRef = useMounterRef();

  // 상태값이 변경되었을 때 실행될 hook
  useEffect(() => {
    // 화면이 마운트 된 후 true값이라면
    if(mountedRef.current) {
      const setParams = {};
      console.log(setParams);

      if(year) {
        setParams.year = parseInt(year);
      }

      // ajax 재요청
      refetch({
        params: setParams,
      });
    }
    // hook 함수 안에서 다른 상태값을 사용할 경우 해당 상태값을 모니터링 해야한다.
  }, [mountedRef, refetch, year]);
  // ------------------------------------------------------- 드롭다운 이벤트 끝


  // ------------------------------------------------------- 에러발생 시작
  if(error) {
    console.error(error);

    return (
      <div>
        <h1>{error.code} Error</h1>
        <p>{error.message}</p>
      </div>
    );
  }
  // ------------------------------------------------------- 에러발생 끝

  const head = ['번호', '년도', '월', '교통사고 건수', '사망자 수', '부상자 수'];

  return (
    <div>
      <select name="year" onChange={onSelectChagne}>
        <option value="">-- 연도 선택 --</option>
        {[...new Array(2018-2005+1)].map((v,i) => 
          <option key={i} value={2005+i}>{2005 + i}</option> 
        )}
      </select>

      {data && (
        <table border='1'>
          <thead align='center'>
            <tr>
              {head.map((v,i) => <th key={i}>{v}</th>)}
            </tr>
          </thead>
          <tbody align='center'>
            {data && data.map(({
              id, year, month, accident, death, injury
            }, i) => {
              return (
                <tr key={i}>
                  <td>{id}</td>
                  <td>{year} 년</td>
                  <td>{month} 월</td>
                  <td>{accident.toLocaleString()} 건</td>
                  <td>{death.toLocaleString()} 명</td>
                  <td>{injury.toLocaleString()} 명</td>
                </tr>
              );
            })}
          </tbody>
          <tfoot>
            <tr>
              <th colSpan={3}>합계</th>
              <th>{data.map((v,i) => v.accident).reduce((a, b) => a + b).toLocaleString()} 건</th>
              <th>{data.map((v,i) => v.death).reduce((a, b) => a + b).toLocaleString()} 건</th>
              <th>{data.map((v,i) => v.injury).reduce((a, b) => a + b).toLocaleString()} 건</th>
            </tr>
          </tfoot>
        </table>
      )}
    </div>
  );
};

export default memo(App);

 

- src/hook/useMounterRef.jsx (커스텀훅)

import React, { useEffect, useRef } from 'react';

// 페이지 로딩이 완료되었음을 감지하기 위한 커스텀 hook
export default function useMounterRef() {

  const mountedRef = useRef(false);

  useEffect(() => {
    // 마운트 후 약간의 시간차를 주고 true로 변경
    setTimeout(() => {
      mountedRef.current = true;
    })
  }, []);

  return mountedRef;
};

 

※ 실행결과

'국비수업 > React' 카테고리의 다른 글

[React/Redux] 비동기 처리  (0) 2022.05.23
[React/Redux] Redux  (0) 2022.05.20
[React] Axios 사용하기  (0) 2022.05.15
[React] Hooks  (0) 2022.04.29
[React] CSS 사용하기  (0) 2022.04.26

+ Recent posts