본문 바로가기
Web Study/한입크기로잘라먹는리액트

한입 크기로 잘라먹는 리액트 - 5

by 쿠리의일상 2023. 3. 31.

React 에서 API 호출하기

useEffect 를 사용하여 컴포넌트의 Mount 시점에 API 를 호출하고 해당 API 의 결과값을 일기 데이터의 초기값으로 이용

 

= fetch() 를 사용하여 API 를 호출 -> API 의 응답 데이터를 App.js 의 data 상태에 저장하여 초기화해주기

 

https://jsonplaceholder.typicode.com/

 

JSONPlaceholder - Free Fake REST API

{JSON} Placeholder Free fake API for testing and prototyping. Powered by JSON Server + LowDB. Tested with XV. Serving ~2 billion requests each month.

jsonplaceholder.typicode.com

해당 사이트의 comments 부분의 api 를 가져온다 (https://jsonplaceholder.typicode.com/comments)

 

api 를 읽어오는 것은 시간이 걸리는 작업이므로 동기처리 해줄 필요가 있다.

이때 async await 를 사용하여 fetch() 를 써준다.

기본적으로 await 를 fetch 앞에 붙여서 변수를 리턴해주는데, 읽어온 데이터는 json 파일이므로 또 한번 .json() 을 사용해줘야 배열 형태로 정제된다.

const res = await fetch('api 주소');
const result = await res.json();

정석적으로 두 줄로 쓸 수 있는 것을 아래처럼 한줄로 표현이 가능하다.

const res = await fetch('api 주소').then((res) => res.json());

 

const getData = async () => {
    const res = await fetch('https://jsonplaceholder.typicode.com/comments')
      .then((res) => res.json());
    // const res = await fetch('https://jsonplaceholder.typicode.com/comments');
    // const result = await res.json();
    // console.log(result);

    const initData = res.slice(0, 20).map((e) => {
      return {
        id: dataId.current++,
        author : e.email,
        content : e.body,
        emotion : Math.floor(Math.random() * 5) + 1,
        created_date : new Date().getTime(),
      }
    });
    setData(initData);
  }

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

읽어온 배열의 수가 많으므로 slice(시작인덱스, 개수) 함수로 잘라준 다음,

map 함수를 사용하여 정보를 일기 형식에 맞춰서 객체에 저장하여 return 해주면 해당 객체로 변환된 배열이 리턴된다.

이 배열을 setData() 에 넣어주면 

 

 

React Developer Tools

크롬 웹 스토어에서 확장 프로그램 설치
... > 도구 더보기 > 확장 프로그램 > 세부정보
시크릿 모드에서 허용과 파일 URL 에 대한 액세스 허용, 사이트 액세스 모든 사이트에서 로 설정!
리액트 프로젝트 npm start 시, 리액트 표시가 주황색이어야 제대로 작동되고 있다는 것이다!

 

리액트 developer 가 작동하고 있으면 개발자 도구에 Components 와 Profiler 탭이 생긴다!

 

Components 탭에선,

컴포넌트 사이의 계층 구조와

컴포넌트가 가지고 있는 속성을 쉽게 확인이 가능하다.

 

컴포넌트 탭에서 톱니바퀴를 누르고 Highlight ... 부분을 체크해주면, 리렌더링 되는 컴포넌트에 하이라이트가 생긴다!!

또한 State 가 변하는 것을 실시간으로 위처럼 확인이 가능하다.

 

 

현재 일기 데이터를 분석하는 함수를 제작하고 해당 함수가 일기 데이터의 길이가 변화하지 않을 때 값을 다시 계산하지 않도록 하는게 목표

useMemo

연산 결과값을 재사용하는 연산 최적화 기법

 

Momoization?

이미 계산 해본 연산 결과를 기억시켜두었다가, 동일한 계산을 시키면 다시 연산하지 않고 기억해두었던 데이터를 반환시키게 하는 방법

캐싱과 유사한 개념

 

 

일기의 감정 점수의 비율을 다루는 함수 구현

 const getDiaryAnalysis = () => {
    console.log('일기 분석 시작');
    const goodCount = data.filter((e) => e.emotion >=3).length;
    const badCount = data.length - goodCount;
    const goodRatio = (goodCount / data.length) * 100;
    return {goodCount, badCount, goodRatio};
  }

  const {goodCount, badCount, goodRatio} = getDiaryAnalysis();

  return (
    <div>
      <DiaryEditor onCreate={onCreate} />
      <div>전체 일기 : {data.length}</div>
      <div>기분 좋은 일기 개수 : {goodCount}</div>
      <div>기분 나쁜 일기 개수 : {badCount}</div>
      <div>기분 좋은 일기 비율 : {goodRatio}</div>
      <DiaryList diaryList={data} onRemove={onRemove} onEdit={onEdit} />
    </div>
  );

getDiaryAnalysis 함수는 App.js 가 리렌더링 될 때마다 계속 실행되므로 일기 수정 등의 감정 점수가 변경되지 않는 시점에도 계속 리렌더링 되어 불필요한 연산이 실행된다.

이런 경우 사용하는 것이 useMemo 훅이다

useMemo(캐싱이 필요한 함수, [변화가 필요한 조건]);

// useMemo의 리턴 값은 함수의 return 값이다.

 

위의 예제를 useMemo 로 만들면,

  const getDiaryAnalysis = useMemo(() => {
    console.log('일기 분석 시작');
    const goodCount = data.filter((e) => e.emotion >=3).length;
    const badCount = data.length - goodCount;
    const goodRatio = (goodCount / data.length) * 100;
    return {goodCount, badCount, goodRatio};
  }, [data.length]);
  
  const {goodCount, badCount, goodRatio} = getDiaryAnalysis;

이런 식인데, data의 개수가 변경될 때만 연산이 실행되어야 하므로 배열에다가 넣어준다.

useMemo() 훅은 리턴값으로 넣어준 함수의 return 이 들어가게 되므로 더이상 함수가 아니게 된다!