본문 바로가기
강의 실습/한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지

React에서 API 호출하기

by Jint 2024. 1. 21.

useEffect X fetch

1. React에서 API 호출하기
세부 목표)
- useEffect 를 이용하여 컴포넌트 Mount 시점에 API 를 호출하고 해당 API 의 결과값을 일기 데이터의 초기값으로 이용하기

무료로 API 서비스를 제공하여 테스트 할 수 있도록 도와주는 JSON Placeholder 서비스를 이용한다. 구글에 'json placeholder' 를 검색하여 홈페이지에 접속한 뒤, Resources 의 '/comment' 에 접속한다. JSON 형태의 객체 배열이 나타나는데, 이 데이터를 사용하기 위해 URL 을 복사한다.
참고링크 : https://jsonplaceholder.typicode.com/comments

App.js 컴포넌트가 Mount 될 때 API 를 호출하여 데이터를 불러와본다. Lifecycle 컴포넌트 호출은 주석처리 한다.

- App.js

import { useEffect, useRef, useState } from 'react';
import './App.css';
import DiaryEditor from './DiaryEditor';
import DiaryList from './DiaryList';
// import Lifecycle from './Lifecycle';

// 임시 배열 데이터
/*
const dummyList = [
    {
        id: 1
      , author: '송진성'
      , content: '하이 1'
      , emotion: 5
      , created_date: new Date().getTime() // 현재 시간 기준 생성됨, getTime() : 시간을 밀리세컨트로 돌려줌
    }
  , {
        id: 2
      , author: '홍길동'
      , content: '하이 2'
      , emotion: 2
      , created_date: new Date().getTime()
    }
  , {
        id: 3
      , author: '아무개'
      , content: '하이 3'
      , emotion: 1
      , created_date: new Date().getTime()
    }
]
*/

// API 링크 : https://jsonplaceholder.typicode.com/comments

function App() {

  const [data, setData] = useState([]); // 빈 배열로 시작 (일기가 없는 상태로 시작)

  const dataId = useRef(0);

  // API 호출하여 JSON 데이터 가져오기
  const getData = async() => {
    const res = await fetch('https://jsonplaceholder.typicode.com/comments').then((res) => res.json());
    console.log(res);
  }

  // Mount
  useEffect(() => {
    getData();
  }, []);

  const onCreate = (author, content, emotion) => {
    const created_date = new Date().getTime();
    const newItem = {
      author,
      content,
      emotion,
      created_date,
      id: dataId.current
    }
    dataId.current += 1;
    setData([newItem, ...data]); // 위에서 부터 출력하기 위해 newItem, ...data 순서로 작성
  };

  const onRemove = (targetId) => {
    console.log(`${targetId}가 삭제되었습니다.`);
    const newDiaryList = data.filter((it) => it.id !== targetId); // targetId 를 포함하지 않은 배열
    setData(newDiaryList); // 데이터의 state 를 바꿈
  };

  const onEdit = (targetId, newContent) => {
    setData(
      data.map((it) => it.id === targetId ? { ...it, content: newContent } : it)
    );
  };

  return (
    <div className="App">
      {/* <Lifecycle /> */}
      <DiaryEditor onCreate={onCreate}/>
      <DiaryList diaryList={data} onRemove={onRemove} onEdit={onEdit} />
    </div>
  );
}

export default App;

 

Mount 시점에 API 호출 결과


500 개의 데이터를 확인할 수 있다. 받아온 데이터를 20개로 잘라서 일기 데이터의 기초 데이터(초기값)로 사용해본다. API 로 호출한 JSON 객체의 'body' 는 본문으로, 'email' 은 작성자로 활용해본다.

- App.js

import { useEffect, useRef, useState } from 'react';
import './App.css';
import DiaryEditor from './DiaryEditor';
import DiaryList from './DiaryList';
// import Lifecycle from './Lifecycle';

// 임시 배열 데이터
/*
const dummyList = [
    {
        id: 1
      , author: '송진성'
      , content: '하이 1'
      , emotion: 5
      , created_date: new Date().getTime() // 현재 시간 기준 생성됨, getTime() : 시간을 밀리세컨트로 돌려줌
    }
  , {
        id: 2
      , author: '홍길동'
      , content: '하이 2'
      , emotion: 2
      , created_date: new Date().getTime()
    }
  , {
        id: 3
      , author: '아무개'
      , content: '하이 3'
      , emotion: 1
      , created_date: new Date().getTime()
    }
]
*/

// API 링크 : https://jsonplaceholder.typicode.com/comments

function App() {

  const [data, setData] = useState([]); // 빈 배열로 시작 (일기가 없는 상태로 시작)

  const dataId = useRef(0);

  // API 호출하여 JSON 데이터 가져와 초기값 설정
  const getData = async() => {
    const res = await fetch('https://jsonplaceholder.typicode.com/comments').then((res) => res.json());
    // 0~19 인덱스까지 자르고, 데이터를 하나씩 순회하여 return 되는 객체 모아서 배열 만듦
    const initData = res.slice(0, 20).map((it) => {
      return {
        author: it.email,
        content: it.body,
        emotion: Math.floor(Math.random() * 5) + 1, // 0~4 까지 랜덤 난수 생성 후 정수로 형변환(소수점 버림) + 1
        created_data: new Date().getTime(), // 현재시간으로 생성 후 밀리세컨드로 바꿈
        id: dataId.current++ // 후위연산자
      }
    });
    setData(initData);
  }

  // Mount
  useEffect(() => {
    getData();
  }, []);

  const onCreate = (author, content, emotion) => {
    const created_date = new Date().getTime();
    const newItem = {
      author,
      content,
      emotion,
      created_date,
      id: dataId.current
    }
    dataId.current += 1;
    setData([newItem, ...data]); // 위에서 부터 출력하기 위해 newItem, ...data 순서로 작성
  };

  const onRemove = (targetId) => {
    console.log(`${targetId}가 삭제되었습니다.`);
    const newDiaryList = data.filter((it) => it.id !== targetId); // targetId 를 포함하지 않은 배열
    setData(newDiaryList); // 데이터의 state 를 바꿈
  };

  const onEdit = (targetId, newContent) => {
    setData(
      data.map((it) => it.id === targetId ? { ...it, content: newContent } : it)
    );
  };

  return (
    <div className="App">
      {/* <Lifecycle /> */}
      <DiaryEditor onCreate={onCreate}/>
      <DiaryList diaryList={data} onRemove={onRemove} onEdit={onEdit} />
    </div>
  );
}

export default App;

 

일기데이터 초기값 설정



참고강의 : https://www.inflearn.com/course/%ED%95%9C%EC%9E%85-%EB%A6%AC%EC%95%A1%ED%8A%B8#

 

한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지 강의 - 인프런

개념부터 독특한 프로젝트까지 함께 다뤄보며 자바스크립트와 리액트를 이 강의로 한 번에 끝내요. 학습은 짧게, 응용은 길게 17시간 분량의 All-in-one 강의!, 리액트, 한 강의로 끝장낼 수 있어요.

www.inflearn.com

댓글