Front/React

API 통신 - react 배우기

oodada 2023. 11. 16. 08:04

API 통신

1. API란?

  • API는 application programming interface의 약자로, 프로그램과 프로그램 사이의 통신을 위한 규약이다.
  • API는 서버와 클라이언트 사이에서 데이터를 주고 받는 방식을 의미한다.

- 비동기 처리

async/await를 사용한 코드

async function fetchData() {
  // API 요청을 보내는 함수 (async : 비동기 함수)
  try {
    // try 블록 안에서 예외가 발생하면 catch 블록이 실행된다.
    const response = await fetch('https://API.example.com/data'); // fetch 메서드를 사용하여 데이터를 가져옴
    const data = await response.json(); // 응답 데이터를 JSON 형태로 변환
    console.log('데이터:', data);
  } catch (error) {
    // 예외 처리
    console.error('에러:', error);
  }
}

// fetchData 함수를 호출
fetchData();

3. axios 라이브러리를 사용한 API 통신

axios는 API 요청을 보내는 라이브러리

  • Axios는 JavaScript에서 사용되는 유명한 HTTP 클라이언트 라이브러리로
  • 웹 브라우저와 Node.js 환경에서 사용될 수 있으며, HTTP 요청을 보내고 받는 기능을 제공합니다.
  • Axios는 Promise 기반의 API를 사용하여 비동기 HTTP 요청을 간편하게 처리할 수 있게 해줍니다.

- Axios 설치

npm install axios
yarn add axios

- Axios 문법 구성

Promise를 사용한 코드

import axios from 'axios';

function fetchData() {
  // API 요청을 보내는 함수 (async : 비동기 함수)
  axios // axios 라이브러리를 사용하여 API 요청을 보냄
    .get('https://API.example.com/data') // get 메서드를 사용하여 데이터를 가져옴
    .then(response => {
      // then 메서드를 사용하여 응답 데이터를 출력
      console.log('데이터:', response.data);
    })
    .catch(error => {
      // catch 메서드를 사용하여 예외 처리
      console.error('에러:', error);
    });
}

fetchData(); // 함수 호출

async/await를 사용한 코드

import axios from 'axios';

async function fetchData() {
  // API 요청을 보내는 함수 (async : 비동기 함수)
  try {
    // try 블록 안에서 예외가 발생하면 catch 블록이 실행된다.
    const response = await axios.get('https://API.example.com/data'); // get 메서드를 사용하여 데이터를 가져옴
    console.log('데이터:', response.data);
  } catch (error) {
    // catch 메서드를 사용하여 예외 처리
    console.error('에러:', error);
  }
}

// fetchData 함수를 호출
fetchData();

- 기본 문법 예제

// SimpleAPIExample.js
// useEffect 추가 : 컴포넌트가 렌더링 될 때마다 특정 작업을 수행할 수 있도록 설정하는 Hook이다.
import React, { useState, useEffect } from 'react';
import axios from 'axios'; // axios 추가 : API 요청을 보내는 라이브러리

function SimpleAPIExample() {
  // 데이터를 저장할 상태를 정의한다.
  // 초기값: null, data : API 요청 결과, setData : API 요청 결과를 저장하는 함수
  const [data, setData] = useState(null);

  // API 요청을 보내는 함수
  useEffect(() => {
    // API 요청을 보내는 함수 (async : 비동기 함수)
    async function fetchData() {
      // try 블록 안에서 예외가 발생하면 catch 블록이 실행된다.
      try {
        const response = await axios.get('https://jsonplaceholder.typicode.com/posts/1');
        // 응답 데이터를 상태에 저장
        setData(response.data);
      } catch (error) {
        // 예외 발생 시
        console.error('Error fetching data', error); // 에러 메시지 출력
      }
    }

    fetchData(); // API 요청 함수 호출
  }, []);

  // 데이터 로딩 중이거나 없을 때의 처리
  if (!data) return <div>Loading...</div>;

  return (
    // API 요청 결과 출력
    <div>
      <h1>{data.title}</h1>
      <p>{data.body}</p>
    </div>
  );
}

export default SimpleAPIExample;

- NFT API 예제

https://jsonplaceholder.typicode.com/photos?_limit=10

[
  {
    "albumId": 1,
    "id": 1,
    "title": "accusamus beatae ad facilis cum similique qui sunt",
    "url": "https://via.placeholder.com/600/92c952",
    "thumbnailUrl": "https://via.placeholder.com/150/92c952"
  },
  {
    "albumId": 1,
    "id": 2,
    "title": "reprehenderit est deserunt velit ipsam",
    "url": "https://via.placeholder.com/600/771796",
    "thumbnailUrl": "https://via.placeholder.com/150/771796"
  },
  {
    "albumId": 1,
    "id": 3,
    "title": "officia porro iure quia iusto qui ipsa ut modi",
    "url": "https://via.placeholder.com/600/24f355",
    "thumbnailUrl": "https://via.placeholder.com/150/24f355"
  },
  ...생략...
]
// NFTCollection.js
import React, { useState, useEffect } from 'react';
import axios from 'axios'; // axios 라이브러리 : API 요청을 보내는 라이브러리
import NFT from './NFT'; // NFT 컴포넌트 파일 임포트

function App() {
  const [nfts, setNfts] = useState([]); // 여러 NFT 데이터를 저장할 배열 상태

  useEffect(() => {
    // 컴포넌트가 렌더링 될 때마다 특정 작업을 수행할 수 있도록 설정하는 Hook
    async function fetchNFTs() {
      try {
        // 여러 NFT 데이터를 가져옴
        const response = await axios.get('https://jsonplaceholder.typicode.com/photos?_limit=10');
        // 가져온 데이터를 원하는 형태로 가공
        const nftData = response.data.map(nft => ({
          image: nft.url,
          name: nft.title,
          author: 'Demo Author',
          bidders: ['bidder1.jpg', 'bidder2.jpg', 'bidder3.jpg'],
          currentbid: '$5000',
          download: nft.thumbnailUrl,
        }));
        setNfts(nftData); // 가져온 데이터로 상태 업데이트
      } catch (error) {
        console.error('Error fetching NFT data', error);
      }
    }

    fetchNFTs();
  }, []);

  return (
    <div>
      {nfts.map((nft, index) => (
        <NFT
          key={index}
          {...nft}
        /> // 각 NFT 데이터에 대한 컴포넌트 생성
      ))}
    </div>
  );
}

export default App;
// NFT.js
import React, { useState } from 'react';
import { Box, Flex, Image, Text, Button, Icon, AvatarGroup, Avatar, Link } from '@chakra-ui/react';
import { IoHeart, IoHeartOutline } from 'react-icons/io5';

function NFT({ image, name, author, bidders, currentbid, download }) {
  const [like, setLike] = useState(false);

  return (
    <Box
      p="20px"
      boxShadow="0px 0px 2px 1px rgba(0,0,0,0.2)"
      borderRadius="20px"
    >
      <Flex
        direction="column"
        justify="center"
      >
        <Box
          mb="20px"
          position="relative"
        >
          <Image
            src={image}
            width="100%"
            height="auto"
            borderRadius="20px"
          />
          <Button
            position="absolute"
            bg="white"
            _hover={{ bg: 'whiteAlpha.900' }}
            _active={{ bg: 'white' }}
            _focus={{ bg: 'white' }}
            top="14px"
            right="14px"
            borderRadius="50%"
            minW="36px"
            h="36px"
            onClick={() => setLike(!like)}
          >
            <Icon
              w="20px"
              h="20px"
              as={like ? IoHeart : IoHeartOutline}
              color="brand.500"
            />
          </Button>
        </Box>
        <Flex
          flexDirection="column"
          justify="space-between"
        >
          <Flex
            justify="space-between"
            mb="auto"
          >
            <Flex direction="column">
              <Text
                fontSize="xl"
                mb="5px"
                fontWeight="bold"
              >
                {name}
              </Text>
              <Text
                color="gray.600"
                fontSize="sm"
              >
                {author}
              </Text>
            </Flex>
            <AvatarGroup
              max={3}
              size="sm"
              fontSize="12px"
            >
              {bidders.map((avt, key) => (
                <Avatar
                  key={key}
                  src={avt}
                />
              ))}
            </AvatarGroup>
          </Flex>
          <Flex
            align="start"
            justify="space-between"
            mt="25px"
          >
            <Text
              fontWeight="700"
              fontSize="sm"
            >
              Current Bid: {currentbid}
            </Text>
            <Link href={download}>
              <Button
                variant="outline"
                colorScheme="blue"
                fontSize="sm"
                fontWeight="500"
                borderRadius="70px"
                px="24px"
                py="5px"
              >
                Place Bid
              </Button>
            </Link>
          </Flex>
        </Flex>
      </Flex>
    </Box>
  );
}

export default NFT;
티스토리 친구하기