Project/Toy-project

๋™๋ฌผ์˜ ์ˆฒ ์ •๋ณด ์›นํŽ˜์ด์ง€ ๋งŒ๋“ค๊ธฐ 1 - API ๋ถˆ๋Ÿฌ์˜ค๊ธฐ

Dong _ hwa 2023. 5. 20. 21:29

๋™๋ฌผ์˜ ์ˆฒ์— ์š”์ฆ˜ ํ‘น ๋น ์ ธ์‚ฌ๋Š”๋ฐ,
๋‚ด๊ฐ€ ์ข‹์•„ํ•˜๋Š” ๊ฑธ๋กœ ๋ญ”๊ฐ€๋ฅผ ๋งŒ๋“ค์–ด๋ณด๋ฉด ๋”์šฑ ํฅ๋ฏธ๊ฐ€ ์ƒ๊ธธ ๊ฑฐ ๊ฐ™์•„์„œ
์ผ๋‹จ ๋ƒ…๋‹ค ๋™๋ฌผ์˜์ˆฒ api๊ฐ€ ์žˆ๋‚˜ ์ฐพ์•„๋ณด์•˜๋‹ค.

API ๋ถˆ๋Ÿฌ์˜ค๊ธฐ

https://api.nookipedia.com/

์—ฌ๊ธฐ์„œ api key๋ฅผ ์š”์ฒญํ•œ๋‹ค๊ณ  ํผ์„ ์ž‘์„ฑํ•ด ๋ณด๋ƒˆ๊ณ ,
๋ณด๋ƒˆ๋”๋‹ˆ ๋ฉฐ์น  ๋งŒ์— ์‘์›ํ•œ๋‹ค๋ฉฐ (ใ…‹ใ…‹) ํ‚ค๋ฅผ ๋ณด๋‚ด์ฃผ์—ˆ๋‹ค.

์ผ๋‹จ ๋ฐ์ดํ„ฐ๋ฅผ ์ž˜ ๋ฐ›์•„์˜ฌ ์ˆ˜ ์žˆ๋‚˜ ํ…Œ์ŠคํŠธ๋ฅผ ํ•ด๋ณด๊ธฐ์œ„ํ•ด
์ฃผ๋ฏผ ๋ชฉ๋ก๋ถ€ํ„ฐ postman ์œผ๋กœ ๋ถˆ๋Ÿฌ์™€ ๋ณด์•˜๋‹ค.

X-API-KEY์— ๋‚ด๊ฐ€ ๋ฐ›์€ ํ‚ค๋ฅผ ๋„ฃ์–ด์ฃผ๊ณ  ํ˜ธ์ถœํ•˜๋ฉด

์ด๋ ‡๊ฒŒ ์ •๋ณด๊ฐ€ ์ญ‰~ ๋ถˆ๋Ÿฌ์™€์ง„๋‹ค.

 

 

 

๋ฆฌ์•กํŠธ๋กœ ์ถœ๋ ฅํ•˜๊ธฐ

ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ

npx create-react-app ์•ฑ์ด๋ฆ„

App key ์ถ”๊ฐ€ํ•˜๊ธฐ

.env

ํ‚ค๋Š” ์ผ๋‹จ ์ˆจ๊ฒจ์•ผ ํ•˜๋Š” ๋‚ด์šฉ์ด๋ฏ€๋กœ,
.gitignore ์—์„œ

# API KEY
.env

๋กœ ์ˆจ๊ฒจ๋†”์ค€๋‹ค.

๊ทธ๋ฆฌ๊ณ  .env ํŒŒ์ผ์—๋Š” ์•„๋ž˜ ๋‚ด์šฉ์„ ์ ์–ด์คŒ

REACT_APP_API_KEY=๋‚ด๊ฐ€ ๋ฐ›์€ API KEY

์ด์ œ ๊ณต์‹๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•ด ๋ถˆ๋Ÿฌ์™€์ฃผ๋ฉด ๋œ๋‹ค.

App.js

import axios from "axios";

function App() {
  const URL = "https://api.nookipedia.com/villagers";

  const response = axios.get(URL, {
    headers: {
      "X-API-KEY": process.env.REACT_APP_API_KEY,
      "Accept-Version": "1.1.0",
    },
  });

  console.log(response);
  return <div className="App"></div>;
}

export default App;

์ฝ˜์†”์ฐฝ์„ ํ™•์ธํ–ˆ์„ ๋•Œ,

์ด๋ ‡๊ฒŒ ๋ถˆ๋Ÿฌ์™€์ง€๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

axios๋ฅผ ์‹คํ–‰ํ–ˆ์œผ๋‹ˆ ์ผ๋‹จ promise ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๊ฐ€ ๋งŒ๋“ค์–ด์ง„ ๊ฒƒ.
์ด์ œ ๋‚˜๋จธ์ง€ ์ฝ”๋“œ๋„ ์ž‘์„ฑํ•ด๋ณธ๋‹ค

 

 

 

 

 

๋น„๋™๊ธฐ ์‹คํ–‰

aysnc await๋ฅผ ์ด์šฉํ•ด์ค€๋‹ค

App.js

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

function App() {
  const [data, setData] = useState(null);
  const [error, setError] = useState(null);
  const URL = "https://api.nookipedia.com/villagers";

  const VillagersData = async () => {
    try {
      setError(null);
      setData(null);
      const response = await axios.get(URL, {
        headers: {
          "X-API-KEY": process.env.REACT_APP_API_KEY,
          "Accept-Version": "1.1.0",
        },
      });
      setData(response.data);
      console.log(response.data);
    } catch (e) {
      setError(e);
    }
  };

  useEffect(() => {
    VillagersData();
  }, []);

  if (error) return <div>error</div>;
  if (!data) return <div>์—†๋‹ค๋Šฅ</div>;

  return <div className="App">{data[0].name}</div>; //Ace ์ถœ๋ ฅ
}

export default App;
  • setError(null), setData(null) : ์š”์ฒญ ์‹œ์ž‘ํ•  ๋•Œ error์™€ data ์ดˆ๊ธฐํ™”
  • const response : API์—์„œ ๋ถˆ๋Ÿฌ์˜จ ๊ฐ’์„ response ๋ณ€์ˆ˜์— ์ €์žฅ
  • setData(response) : response ๊ฐ’์„ data์— ์ €์žฅ!

๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์™”๋‹ค...



 

 

 

ํ™”๋ฉด์— ๋ฆฌ์ŠคํŠธ ์ถœ๋ ฅ

ํ™”๋ฉด์— ์ฃผ๋ฏผ๋ชฉ๋ก์„ ๋ฝ‘์•„์ฃผ๊ธฐ ์œ„ํ•ด ๋”ฐ๋กœ ํŒŒ์ผ์„ ๋งŒ๋“ค์—ˆ๋‹ค.

Villagers.js

import React from "react";

function Villagers({ name, gender, image_url, species }) {
  return (
    <div>
      <h2>{name}</h2>
      <img src={image_url} alt="์ด๋ฏธ์ง€" />
      <h4>์„ฑ๋ณ„ : {gender}</h4>
      <h4>์ข…๋ฅ˜ : {species}</h4>
      <br></br> <br></br>
    </div>
  );
}

export default Villagers;

์—ฌ๊ธฐ์„  <img src={image_url} alt="์ด๋ฏธ์ง€" />
์ด ๋ถ€๋ถ„์—์„œ ํ•œ ๋ฒˆ ์‹ค์ˆ˜๊ฐ€ ์žˆ์—ˆ๋Š”๋ฐ, ์‚ฌ์ง„์ด ์—‘๋ฐ•์ด ๋–ด์—ˆ๋‹ค.
์ด์œ ๋Š” { } ์ด๊ฑธ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  " " ์ด๊ฑธ ์‚ฌ์šฉํ•ด์„œ image_url ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ์•„์˜ˆ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ์ง€ ์•Š์•˜๋‹ค.

 

App.js

	...
    
return (
  <div className="App">
     {data.map((item) => {
        return (
          <Villagers
          		key={item.id}
     			name={item.name}
      			species={item.species}
      			gender={item.gender}
      			image_url={item.image_url}
      	/>
        );
    })}
  </div>
);

return ๋ถ€๋ถ„์— ์ž๋ฃŒ๋ฅผ ์ถœ๋ ฅํ•ด์ค„ ๊ตฌ๋ฌธ์„ ์งœ๋ฉด ๋œ๋‹น

ใ…‹ใ…‹ใ…‹ใ…‹๐Ÿ˜‚ ์™œ์ผ€ ์›ƒ๊ธฐ๋ƒ ์‚ฌ์ง„ ์‚ฌ์ด์ฆˆ๊ฐ€ ์ œ๋ฉ‹๋Œ€๋กœ๋‹ˆ๊นŒ ์ด๋ถ€๋ถ„ ์ˆ˜์ •ํ•ด์ฃผ๋ฉด ์ผ๋‹จ ๋™์ผ

<img src={image_url} alt="์ด๋ฏธ์ง€" width={"150px"} />


(App.css๋ฅผ ๋ถˆ๋Ÿฌ์™€์„œ ๊ฐ€์šด๋ฐ ์ •๋ ฌ์ด ๋˜์—ˆ๋‹ค)
์•„๋ฌดํŠผ ๊ฑฐ์˜ 500๋งˆ๋ฆฌ์˜ ์ฃผ๋ฏผ์ด ํ•„์š”ํ•œ ์ •๋ณด๋“ค๋งŒ ๊ณจ๋ผ์„œ ๋ถˆ๋Ÿฌ์™€์กŒ๋‹ค.



 

์•ฝ๊ฐ„์˜ css

display: flex
๋ฅผ ํ•ด์ฃผ๋ฉด ๋„ˆ~๋ฌด๋‚˜ ๋‹น์—ฐํ•˜๊ฒŒ๋„


์ด๋ ‡๊ฒŒ ๋ฐฐ์น˜๊ฐ€ ๋œ๋‹ค. (์‚ฌ์ง„ ์‚ฌ์ด์ฆˆ๋Š” height์— ๋งž์ถฐ์ค˜์•ผ๊ฒ ์Œ)
๊ทผ๋ฐ 500๊ฐœ๊ฐ€ ์ „๋ถ€ ๊ฐ€๋กœ๋กœ ๋†“์—ฌ์žˆ์œผ๋ฉด ๋ณด๊ธฐ๊ฐ€ ํž˜๋“œ๋‹ˆ๊น ์ˆ˜์ •ํ•ด์ฃผ๊ณ  ์‹ถ์—ˆ๋‹ค

 

 

flex-wrap: wrap

ํ•ด์ฃผ๊ณ  villagers.js์—์„œ๋„ ๊ฐ๊ฐ margin์„ ์ฃผ์—ˆ๋‹ค.

 

 


์˜ค๋Š˜์€ ์—ฌ๊ธฐ๊นŒ์ง€!
api์†Œ์Šค๋Š” ๋ฌผ๊ณ ๊ธฐ, ๊ณค์ถฉ, ํ™”์„... ๋‹ค์–‘ํ•œ ์ •๋ณด๊ฐ€ ์žˆ๊ณ 
์˜ค๋Š˜์€ ์ผ๋‹จ ์ฃผ๋ฏผ๋งŒ ๋ถˆ๋Ÿฌ์™€ ๋ดค๋‹ค.
์ด์ œ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๊ฑฐ, ๋ฟŒ๋ ค์ฃผ๋Š” ๊ฑฐ ๋‹ค ํ•ด๋ดค์œผ๋‹ˆ ์–ด๋–ป๊ฒŒ ๋งŒ๋“ค์ง€ ์ƒ๊ฐ๋งŒ ํ•˜๋ฉด ๋œ๋‹ค. ใ…  ใ… 

๊ณต๊ณต ์˜คํ”ˆapi๋Š” ์—ฌ๊ธฐ์ €๊ธฐ ์ •๋ณด๊ฐ€ ๋งŽ์€๋ฐ ์ด๊ฑด ๋ญ ํ•˜๋‚˜๋„ ์—†์–ด์„œ...
๊ณ„์† ๋งจ๋•…์— ํ•ด๋‹นํ•˜๋Š” ๊ธฐ๋ถ„์œผ๋กœ ํ•˜๊ณ  ์žˆ๋‹ค ใ…  ใ… 
๊ทธ๋ž˜๋„ ์–ด๋–ค ์ผ ํ•˜๋‚˜๋ฅผ ์•„์ฃผ 0์ธ ์ƒํƒœ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๋Š” ๊ฑด ์ฒ˜์Œ์ด๋‹ˆ(?)
์ตœ์„ ์„ ๋‹คํ•ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค ํ‘ํ‘
๊ทธ๋ž˜๋„ ๋‚ด๊ฐ€ ์Šค์Šค๋กœ ์นœ ์ฝ”๋“œ๋กœ ์ด๋ ‡๊ฒŒ ํ™”๋ฉด์— ๋”ฑ! ๋‚˜์˜ค๋‹ˆ๊นŒ ๋„ˆ๋ฌด ๋ฟŒ๋“ฏํ•œ๋””...