ReactJS Course [7] - How To Fetch Data From an API in React

최윤서·2024년 9월 8일

.

API

API란, 간단하게 내가 외부에서 가져와서 내 프로그램 안에 쓸 수 있는 데이터를 말한다.

데이터를 묘사하는 json으로 되어있다.

https://catfact.ninja/fact

이 링크는 랜덤한 고양이에 대한 사실을 알려주는 api이다.

fetch()

이제 위에 나오는 고양이 사실을 React app에 가져와서 fetch해보자.

fetch("https://catfact.ninja/fact")
    .then((res) => res.json())
    .then((data => {console.log(data);
}))

먼저 fetch() 함수를 통해서 api링크에 있는 데이터를 가져올 수 있다.
그리고 fetch().then()을 이용하여 응답 객체를 받아온다.
fetch가 받아온 응답 객체인 res를 res.json으로 json 형식으로 변환해준다.
json으로 변환된 data를 console에 출력한다.

Axios

Axios.get("https://catfact.ninja/fact").then((res) => {
    console.log(res.data);
})

위의 것과 같은 방법을 axios를 이용해서 할 수 있다.

Axios.get("https://catfact.ninja/fact").then((res) => {
            setCatFact(res.data.fact);
        })

그러나 이 상태에서는 catFact가 무한히 바뀌게 된다.
컴포넌트가 새로고침 될 때마다 렌더링이 실행되는데, 그 때 setCatFact를 설정함녀서 또 새로고침이 되기 때문이다.

따라서 useEffect를 사용하면 이 문제가 해결된다.
useEffect는 컴포넌트가 렌더링(화면에 그려지는 것) 될 때, 특정한 작업을 실행하도록 한다.

useEffect(() => {
  // 여기서 실행하고 싶은 작업을 작성해요!
}, [의존성 배열]);

실행하고 싶은 함수를 설정하고, 의존성 배열에 어떠한 값을 넣으면 그 값이 변화할 때마다 useEffect가 실행된다.

useEffect (() => {
        Axios.get("https://catfact.ninja/fact").then((res) => {
                setCatFact(res.data.fact);
            });
    }, [])

이렇게 하면 useEffect에 의해서 비어있는 의존성 배열을 보고 컴포넌트가 처음 실행될 때 한 번만 useEffect가 나타나게 된다.

import "./App.css";
import Axios from "axios";
import { useState, useEffect } from "react";


function App () {
    const [catFact, setCatFact] = useState("");

    const fetchCatFact = () => {
            Axios.get("https://catfact.ninja/fact").then((res) => {
                setCatFact(res.data.fact);
            });
    }
    
    useEffect (() => {
        fetchCatFact();
    }, [])

    return (
        <div className = "App">
            <button onClick={fetchCatFact}> Generate Cat Fact </button>
            <p>{catFact}</p>
        </div>
    )
}

export default App;

결론적으로, 위의 코드는 먼저 fetchCatFact함수를 정의하여 Axios를 이용해 api에서 정보를 끌어다가 json을 js 객체로 만들어 catFact의 값을 변화시킨다.

그리고 useEffect를 사용하여 유저가 보는 첫 화면부터 catFact가 보이도록 한다. (fetchCatFact가 실행되면서 리렌더링되니까)

그리고 유저가 버튼을 누를 경우, fetchCatFact를 실행시켜서 유저에게 새로 api에서 가져온 정보를 보여주게 된다!

api에서 검색하기

agify.api를 이용해서 이름을 검색하면 유추되는 나이를 보여주는 프로그램을 만들어보자.

import "./App.css";
import Axios from "axios";
import { useState, useEffect } from "react";


function App () {

    const fetchData = () => {
        Axios.get("https://api.agify.io/?name=")
    };

    return (
        <div className = "App">
            <input placeholder="Guess the age!"></input>
            <button onClick={fetchData}> Generate Cat Fact </button>

            <h1>Predicted age</h1>
        </div>
    )
}

export default App;

이 프로그램이 검색한 이름에 대한 데이터를 불러오려면, input에 입력된 텍스트를 api 링크에 덧붙여서 해당 이름에 대한 링크를 찾고, 가져와서 보여주어야 한다.

 <div className = "App">
            <input placeholder="Guess the age!" onChange={(event) => {setName(event.target.value)}}></input>
            <button onClick={fetchData}> Generate Cat Fact </button>

            <h1>Predicted age</h1>
        </div>

먼저 인풋에 들어오는 글자에 따라, event의 데이터를 이름으로 세팅한다.
그리고 위에 있던 링크에 이어 이름을 붙여주면 되는데... "링크"+name 처럼 써서 자바스크립트식 스트링 더하기를 해줘도 되지만, 변수를 스트링 안에 포함하고 싶다면 방법이 있다.

Axios.get(`https://api.agify.io/?name=${name}`)

이렇게 백틱 사이에 string을 두고 ${} 안에 넣고 싶은 변수를 추가하면 스트링 안에 변수를 넣을 수 있다! (참고로 맥북에서 백틱을 입력하는 방법은 옵션키+₩이다.)

 Axios.get(`https://api.agify.io/?name=${name}`).then((res)=>setPredictedAge(res.data.age))

그리고 이렇게 가져온 데이터를 PredictedAge를 세팅하는 useState를 이용해 세팅해주고, 표시해주면 된다.

import "./App.css";
import Axios from "axios";
import { useState, useEffect } from "react";


function App () {

    const [name, setName] = useState("");
    const [predictedAge, setPredictedAge] = useState(0);
    const fetchData = () => {
        Axios.get(`https://api.agify.io/?name=${name}`).then((res)=>setPredictedAge(res.data.age));
    };

    return (
        <div className = "App">
            <input placeholder="Guess the age!" onChange={(event) => {setName(event.target.value)}}></input>
            <button onClick={fetchData}> Search </button>

            <h1>{predictedAge}</h1>
        </div>
    )
}

export default App;

만약 이 api에 있는 나이 뿐만 아니라 다른 정보 (count, name)도 같이 가져오고 싶으면 fetch하는 대상을 전체 데이터로 두고, predicted age를 object로 가져온다.

<h1>{predictedAge.age}</h1>

데이터를 객체로 가져왔기 때문에 위와 같이 표시해주면 되는데, 이렇게 쓰면 첫 렌더링 당시에는 객체를 가지고 오지 않은 상태라서 띄울 수 있는 게 없다.

때문에 이렇게 적어서 predictedAge가 존재할 때만 age에 접근하게 만들어주면 된다.

<h1>{predictedAge?.age}</h1>

최종 결과물

import "./App.css";
import Axios from "axios";
import { useState, useEffect } from "react";


function App () {

    const [name, setName] = useState("");
    const [predictedAge, setPredictedAge] = useState(0);
    const fetchData = () => {
        Axios.get(`https://api.agify.io/?name=${name}`).then((res)=>setPredictedAge(res.data.age))
    };

    return (
        <div className = "App">
            <input placeholder="Guess the age!" onChange={(event) => {setName(event.target.value)}}></input>
            <button onClick={fetchData}> Search </button>

            <h1>{predictedAge}</h1>
        </div>
    )
}

export default App;
profile
일 잘 하고싶은 기개디자이너

0개의 댓글