How to fetch data with React Hooks 정리

이춘길·2021년 11월 18일
0

React

목록 보기
6/9
post-thumbnail
post-custom-banner

목표

  • React Hooks에서 fetch data 사용 방법 확인

1. React Hooks로 데이터 가져오기

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

function App() {
  const [data, setData] = useState({ hits: [] });

  useEffect(() => {
    const fetchData = async () => { // (1)
      const result = await axios(
        'https://hn.algolia.com/api/v1/search?query=redux',
      );

      setData(result.data);
    };

    fetchData();
  }, []); // (2)

  return (
    <ul>
      {data.hits.map(item => (
        <li key={item.objectID}>
          <a href={item.url}>{item.title}</a>
        </li>
      ))}
    </ul>
  );
}

export default App;
  1. async / await 문법은 암시적으로 반환 값이 있음을 의미한다. 결과적으로, useEffect Callback 함수 대신에 내부적으로 fetch용 async / await 함수를 선언해야 한다.

  2. 해당 useEffect는 Element가 그려진 직 후, 호출된다.


2. useEffect 트리거

  • props, state 데이터와의 결합으로 트리거를 형성할 수 있다.
function App() {
  const [data, setData] = useState({ hits: [] });
  const [query, setQuery] = useState('redux');
  const [url, setUrl] = useState(
    'https://hn.algolia.com/api/v1/search?query=redux',
  );

  useEffect(() => {
    const fetchData = async () => {
      const result = await axios(url); // (3)

      setData(result.data);
    };

    fetchData();
  }, [url]);

  return (
    <Fragment>
      <input
        type="text"
        value={query}
        onChange={event => setQuery(event.target.value)}
      /> // (1)
      <button
        type="button"
        onClick={() =>
          setUrl(`http://hn.algolia.com/api/v1/search?query=${query}`)
        }
      > // (2)
        Search
      </button>

      <ul>
        {data.hits.map(item => (
          <li key={item.objectID}>
            <a href={item.url}>{item.title}</a>
          </li>
        ))}
      </ul>
    </Fragment>
  );
}
  1. 사용자를 통해 Query Data를 입력 받는다.
  2. Search 버튼 클릭 시, 입력 받은 query state를 이용하여 검색 url을 갱신한다.
  3. url 변경이 감지되면 useEffect가 동작하고 데이터 패칭을 수행한다.

3. 커스텀 Hook을 통한 Data fetching

  • API 호출 전용 Hook을 통해 Data fetching 수행
import React, { Fragment, useState, useEffect } from 'react';
import axios from 'axios';

const useDataApi = (initialUrl, initialData) => {
  const [data, setData] = useState(initialData);
  const [url, setUrl] = useState(initialUrl);
  const [isLoading, setIsLoading] = useState(false);
  const [isError, setIsError] = useState(false);

  useEffect(() => {
    const fetchData = async () => {
      setIsError(false);
      setIsLoading(true);

      try {
        const result = await axios(url);

        setData(result.data);
      } catch (error) {
        setIsError(true);
      }

      setIsLoading(false);
    };

    fetchData();
  }, [url]);

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

4. useEffect data fetching 중단

  • 해당 컴포넌트가 마운트 해제가 되었음에도 상태가 설정되는 이슈
  • 마운트 해제된 컴포넌트 상태 설정 방지
  • 내부 분기 처리 로직을 통해 해결
const useDataApi = (initialUrl, initialData) => {
  const [url, setUrl] = useState(initialUrl);
  const [state, dispatch] = useReducer(dataFetchReducer, {
    isLoading: false,
    isError: false,
    data: initialData,
  });

  useEffect(() => {
    let didCancel = false;
    const fetchData = async () => {
      dispatch({ type: 'FETCH_INIT' });
      try {
        const result = await axios(url);
        if (!didCancel) {
          dispatch({ type: 'FETCH_SUCCESS', payload: result.data });
        }
      } catch (error) {
        if (!didCancel) {
          dispatch({ type: 'FETCH_FAILURE' });
        }
      }
    };
    fetchData();
    return () => {
      didCancel = true;
    };
  }, [url]);

  return [state, setUrl];
};

출처

How to fetch data with React Hooks

profile
일지를 꾸준히 작성하자.
post-custom-banner

0개의 댓글