Skip to content

Custom Hooks

Junho Lee edited this page Nov 29, 2019 · 1 revision

Custom Hook

커스텀 훅을 이용해서 서버에 데이터를 요청해보자

  • 일단 훅은 이렇게 생겼다.
  • useGetFeed<T> 라는 제네릭 타입을 갖는다고 명시해 뒀다. 서버에서 주는 데이터의 형식이 그때그때 다르기 때문.
  • 리턴값은 총 5개
    • data 는 말그대로 데이터
    • setData 는 데이터를 변경하는 함수
    • isLoading 은 boolean 변수고 현재 데이터를 가져오고 있으면 true 값을 갖는다.
    • isError 는 데이터를 가져오는 과정에서 에러가 발생하는 경우 true 가 되고 에러처리를 해주면 된다.
    • setUrl 은 약간 이 훅을 발동 시키는 역할이다. 커스텀 훅 내부에서 useEffect 에 dependency를 url 스테이트에 걸어두었기 때문.
import React, { useState, useEffect } from 'react';
import axios from 'axios';

const useGetFeed = <T>(initData:T)
  :[{data:T, setData:React.Dispatch<T>, isLoading:boolean, isError:boolean}, (url:string)=>void ] => {
 ...

  return [{
    data, setData, isLoading, isError,
  }, setUrl];
};

export default useGetFeed;

내부는 이렇게 생겼다. 코드가 기니까 주석으로 ㄱㄱ

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

const useGetFeed = <T>(initData:T)
  :[{data:T, setData:React.Dispatch<T>, isLoading:boolean, isError:boolean}, (url:string)=>void ] => {
  const [data, setData] = useState(initData); // 사용자가 입력한 초기데이터로 data를 세팅한다. 근데 보통 빈배열이거나 빈객체 일듯??
  const [url, setUrl] = useState(''); // 여기서 setUrl로 url 값이 바뀌면 useEffect가 실행된다.
  const [isLoading, setIsLoading] = useState(false);
  const [isError, setIsError] = useState(false);

  useEffect(() => {
    const fetchData = async () => {
      setIsError(false); // 에러가 없다라고 하고 시작
      setIsLoading(true); // 로딩중이다라고 하고 시작

      try {
        const result = await axios(url); // 서버에 데이터 요청
        if (!result.data.success) {
          // 요청이 실패했다면 로딩을 false로 설정한다. 지금은 잘 동작하지 않는데 여기서 에러를 던지던가 해야할듯?
          setIsLoading(false); 
        } else {
          // 요청이 성공했다면 데이터를 세팅하고 로딩은 false로 해서 로딩 멈춰주고 isError는 왜저렇게 했지? 고치자
          console.log(result.data);
          setData(result.data.data);
          setIsLoading(false);
          setIsError(true);
        }
      } catch (e) {
        setIsError(e);
      }
    };
    fetchData();
  }, [url]); // 디펜던시를 url state에 걸어서 url이 바뀔때마다 fetchData()를 실행한다.

  return [{
    data, setData, isLoading, isError,
  }, setUrl];
};

export default useGetFeed;

사용할때는 이렇게 했다. isLoadingtrue 일때는 로딩중이라는 컴포넌트를 띄우고 false 면 로딩이 끝낫고 데이터가 왔다는 뜻이기 때문에 우리가 원하는 데이터를 렌더링 할 수 있다.

const [{
    data, setData, isLoading, isError,
}, setUrl] = useGetFeed<IData | null>(null);

useEffect(() => {
    setUrl(url);
}, [data]);


const WorksDetail:React.FC<WorksDetailProp> = ({
  data, isLoading, isError, commentRef, changeInputHandler, addNewComment,
}) => (
  isLoading || data === null
    ? (<div>Loading...</div>)
    : (
      <S.Container/>

1. 그라운드 룰

2. 스크럼 hackmd link

3. 변경 내역

4. 스프린트

5. 기술공유

6. 팀 회고록

Clone this wiki locally