[React] 컴포넌트에서 API 호출하기

youngseo·2022년 7월 31일
0

REACT

목록 보기
26/52
post-thumbnail

컴포넌트에서 API 호출하기

1. fetch API

fetch API는 브라우저에 내장되어 있는 웹API입니다. 따라서 별도의 다운로드 없이 fetch API를 사용할 수 있습니다.

api호출의 경우 useEffect(()=>{}, [])에서 많이 사용이 됩니다. 또한 이렇게 반환된 응답값을 useState로 관리를 합니다.

import React, { useEffect, useState } from "react";
import { Link } from "react-router-dom";

export default function ReactPage() {
  // api call -> react에 해당하는 글의 목록을 응답 받음.

  const [docs, setDocs] = useState([]);

  useEffect(() => { //useEFfect안에서
    async function fetchData() { //fetch호출
      const res = await fetch("https://jsonplaceholder.typicode.com/posts");
      const result = await res.json();
      setDocs(result);  //호출된 값을 setSState시킴
    }
    fetchData();
  }, []);

  return (
    <div>
      {docs.map((doc) => (
        <Link
          to={`${doc.id}`}
          key={doc.id}
          style={{ display: "block", margin: "1rem 0" }}
        >
          {doc.title}
        </Link>
      ))}
    </div>
  );
}
import React, { useEffect, useState } from "react";
import { useParams, useNavigate } from "react-router-dom";

export default function ReactDocPage() {
  const [childDoc, setChildDoc] = useState({
    id: "",
    title: "",
    body: "",
  });
  // docID: 1, 2, 3....
  const params = useParams();

  const navigate = useNavigate();

  console.log("params", params);

  useEffect(() => {
    async function FetchChild() {
      const res = await fetch(
        `https://jsonplaceholder.typicode.com/posts/${params.docId}`
      );
      const result = res.json;
      console.log(result);
      setChildDoc({
        ...result,
      });
    }
    FetchChild();
  }, []);

  return (
    <>
      <h5 onClick={() => navigate("/")}>logo</h5>
      <div>ReactDocPage ##{params.docId}</div>
      <div>{childDoc.title}</div>
      <div>{childDoc.body}</div>
    </>
  );
}

2. Axios API

axios의 경우 자동으로 JSON데이터를 변환시켜줍니다. 또한 요청 및 응답 인터셉트가 가능하며 타이머 처리도 가능하다는 장점이 있습니다.

Can I use를 통해 fetch호환성을 체크해보면 호환되지 않는 브라우저도 있는데 axios는 호환성이 좋다는 장점이 있습니다.

단, axios는 내장된 라이브러리가 아니기 때문에 패키지를 설치해줘야합니다.

$ yarn add axios
  useEffect(() => {
    async function fetchData() {
      const res = await fetch("https://jsonplaceholder.typicode.com/posts");
      const result = await res.json();
      setDocs(result);
    }
    fetchData();
  }, []);

를 axios로 변경해보면 아래와 같습니다.

  useEffect(() => {
    async function fetchData() {
      const { data } = await axios({
        url: "https://jsonplaceholder.typicode.com/posts",
        methods: "GET",
      });
      setDocs(data);
    }
    fetchData();
  }, []);

get메소드를 사용하는 경우 아래와 같이 사용을 할수도 있습니다.

const {data} = axios.get("https://jsonplaceholder.typicode.com/posts")

3. useEffect 내에서 API호출시 주의할 점

+ ⭐PLUS

만약 API호출을 하는 함수 외부에서 결과값을 사용하는 경우 아래와 같이 then체이닝을 통해 promise기반 데이터를 처리할 수 있습니다.

  useEffect(() => {
    async function fetchData() {
      const { data } = await axios({
        url: "https://jsonplaceholder.typicode.com/posts",
        methods: "GET",
      });
      return data;  //✅결과 값 반환
    }
    fetchData().then((res) => { //then 메소드 체이닝
      setDocs(res);
    });
  }, []);

그런데 위 로직의 경우 useEffect내부에 함수가 있는데 그 함수 내부에서 async 함수를 하나 더 만들어 사용을 하고 있습니다. 그리고 나서 별도로 호출을 하는 방식으로 구현이 되어 있습니다.

이번에는 이렇게 내부에 함수르 하나더 만들지 않고 아래와 같이 작성을 해보겠습니다.

  useEffect(async () => {
    const { data } = await axios.get(
      "https://jsonplaceholder.typicode.com/posts"
    );
    setDocs(data);
  }, []);

확인을 해보면 정상적으로 호출이 되지만 warning메세지가 뜨는 것을 확인할 수 있습니다.

useEffect 콜백함수는 첫번째 인자로 넘긴 함수는 아무것도 반환하지 않거나 retrun () => {}와 같이 반환을 해야하는데 위와 같이 선언 하는 경우 async함수가 리턴한 값은 promise가 되기 때문에 위와 같이 사용하지 말라는 warning메세지가 뜨는 것입니다.

따라서 처음 사용 했던 아래와 같은 방식으로 API를 호출해야합니다.

  useEffect(() => {
    async function fetchData() {
      const { data } = await axios({
        url: "https://jsonplaceholder.typicode.com/posts",
        methods: "GET",
      });
     setDocs(data)
    }
     fetchData()
    });
  }, []);

0개의 댓글