[간단 일기장] 최적화1-useMemo

미아·2023년 1월 6일
0

REACT

목록 보기
20/41


=> 즉 컴퓨터 프로그램이 동일 계산 반복해야할때, 이전에 계산한 값을 메모리에 저장해서 반복 수행 제거하여 프로그램 수행속도 빠르게 하는것!

리액트에서의 memoization

  • 컴포넌트 props가 바뀌지 않을때 리랜더링되는것 방지

감정일기에 useMemo대입하기

  • 1~2 안좋은 감정
  • 3~5 좋은 감정

리랜더링되는이유?

코드에서 데이터가 20개로 잘려서 다시 setData를 호출하면서, 데이터가 바뀌고, app 컴포넌트가 리랜더됨-> 안 코드 재생성되면서 두번 실행하는것임

최적화해야하는이유(useMemo 사용)

  • 지금 구하려고 하는것은

    => 수정을 한다고 해서, 연산의 값에 영향 미치지 않음
    => 즉, 연산하는 함수에 useMemo 사용하기! (원래 하려고했던 함수를 감싸고, 두번째 인자로 어떤값이 변화할때만 다시 수행할지 넣어주기!)


=> 호출할때는 함수가 아니라, 변수만 호출하면 되는것임!!

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

function App() {
  // app -> editor 적용할 데이터
  const [data, setData] = useState([]); // 빈 배열, 앞으로 채워넣을것임
  const dataId = useRef(0);

  const getData = async () => {
    const url = "https://jsonplaceholder.typicode.com/comments";
    const res = await fetch(url).then((res) => res.json());
    //json값만 뽑아오는것(promise객체로 리턴하면서 resolve값을 json()사용해서 변수 res에 담아라!), then은 무조건 들어야하는것임
    // console.log(res);
    /* 이렇게도 쓸수있음 */
    // const url = "https://jsonplaceholder.typicode.com/comments";
    // const res2 = await fetch(url);
    // const response = await res2.json();

    const initData = res.slice(0, 20).map((it) => {
      return {
        author: it.email,
        content: it.body,
        emotion: Math.floor(Math.random() * 5) + 1,
        created_date: new Date().getTime(),
        //return바로 되어서 후에 +1할수없으니까
        id: dataId.current++,
      };
    });
    //res배열 500개여서 20개만 자른다(0~19) - slice
    //Math.random() * 5 => 0~4까지 랜덤난수 생성 , floor이용해서 내림 +1 (1~5까지)
    setData(initData);
  };

  //실행할 시점: app 컴포넌트가 마운트 되자마자!
  useEffect(() => {
    getData();
  }, []);

  // 전달해줄 함수 onCreate
  const onCreate = (author, content, emotion) => {
    const created_date = new Date().getTime();
    const newItem = {
      author, // 비구조화 할당맞다, 키랑 이름 맞추면 그대로 들어감
      content,
      emotion,
      created_date,
      id: dataId.current,
    };
    dataId.current += 1; //current에 1 더해줘야함
    setData([newItem, ...data]); //setData를써야
  };

  // 삭제해줄 함수 onRemove , 어떤 아이디를 갖고있는 애를 지우면 됨!
  const onRemove = (targetId) => {
    console.log(`${targetId}가 삭제되었습니다.`);
    const newDiaryList = data.filter((it) => it.id !== targetId); //다른것만 뉴배열에 넣어라~
    console.log(newDiaryList); // 기억하기!! setData함수 안쓰면 삭제는 진행 안됨!
    setData(newDiaryList);
  }; // 얘를 지우려면, DiaryItem에 가서 지워야함(컴포넌트 전달은 부모인 DiaryList에게!)

  // 수정해줄 함수 onEdit
  const onEdit = (targetId, newContent) => {
    //targetId, newContent 받아가지고와서 => 그 아이디 일치하는 애만 바꿔주면됨
    //데이터 바꾸려면 ? setData()사용~
    //새로운 데이터를 넘겨줘야함!
    setData(
      data.map(
        (it) => (it.id === targetId ? { ...it, content: newContent } : it)
        // ...it 들어온 데이터 뿌려주고, content만 새로운 content로!
      )
    );
  };

  // useMemo실습: 좋은감정, 안좋은감정 나누기
  const getDiaryAnalysis = useMemo(() => {
    console.log("일기 분석 시작");

    //좋은 일기 개수
    const goodCount = data.filter((it) => it.emotion >= 3).length;
    //안좋은 일기 개수
    const badCount = data.length - goodCount;
    //좋은 일기 비율
    const goodCountRatio = (goodCount / data.length) * 100;
    //전체일기를 화면에 찍어줄것임 => return필요, 여러개니까 객체로 리턴
    return { goodCount, badCount, goodCountRatio };
  }, [data.length]); //두번째 인자 배열에 전달한 값이 바뀔때만 다시 수행함!
  const { goodCount, badCount, goodCountRatio } = getDiaryAnalysis; //비구조화할당 이용해서 리턴값 변수에 담아주고(키로 구분), 함수 호출
  return (
    <div className="App">
      <DiaryEditor onCreate={onCreate} />
      <div>전체일기:{data.length}</div>
      <div>기분 좋은 일기 개수:{goodCount}</div>
      <div>기분 나쁜 일기 개수:{badCount}</div>
      <div>기분 좋은 일기 비율:{goodCountRatio}</div>
      <DiaryList onRemove={onRemove} diaryList={data} onEdit={onEdit} />
      {/* prop으로 전달함!(부모=> 자식컴포넌트로 데이터 전달!) */}
    </div>
  );
}

export default App;
profile
새로운 것은 언제나 재밌어 🎶

0개의 댓글