React
React_기초다지기_하루정리(최적화 1 - 연산 결과 재사용)
SanL
2023. 5. 30. 01:55
React
⚑목표 : 연산 결과값을 재사용 하는 방법!
- 현재일기 데이터를 분석하는 함수를 제작하고, 해당함수가 일기 데이터의 길이가
변화하지 않을 때 값을 다시 계산하지 않도록 한다 - Memoization 이해하기
[Memoization 이란?]
이미 계산 해 본 연산 결과를 기억해 두엇다가
동일한 계산을 시키면, 다시 연산하지 않고 기억해 두었던 데이터를 반환 시키게 하는 방법
//마시 시험을 볼때, 이미 풀어본 문제는 다시 풀어보지 않아도 답을 알고 있는 것과 유사한 느낌.
[useMemo : 연산 최적화]
- useMemo의 사용방법 : 우리가 Memoization해주고 싶은 함수를 감싸주면됨
즉, useMemo는 첫번째 인자를 콜백함수로 받아서 콜백함수가 retrun하는 값들을 최적화할 수 있도록 도와주는 그런 기능을 한다.
또한, 두번째 파라미터는 useEffect와 같이 의존성 배열을 받게 되는데, []안에 들어간 어떤 상태의 값이 변하게 되면 콜백함수를
실행하게 되고, 만약 그렇지 않으면 콜백함수는 랜더링 되지않음
<또한, useMemo라는 함수는 어떤 함수를 전달받아서 콜백함수가 리턴하는 값을 다시 리턴하게되는 것 !> 최적화된 함수를 가져다 쓸
경우에는 ()로 받는 것이 아니라 함수명, 값으로 받는다. - 어떤 함수가 있고, 그 함수가 어떤 값을 리턴하고 있는 경우, 리턴까지의 값을 최적하고 싶을 떄가 있다.
(어떤 정보를 수정할 때, 랜더링 하지 않아도되는 부분까지 지속적으로 불필요한 랜더링이 되는 경우 등이 발생할 수 있음)
이럴떄 useMemo를 통해 값을 최적화 할 수 있음.
[일기 리스트 정보 출력]
import { useMemo, useEffect, useRef, useState } from "react";
import "./App.css";
import DiaryEditor from "./DiaryEditor";
import DiaryList from "./DiaryList";
function App() {
const [data, setData] = useState([]); //우리는 여기에 일기 리스트를 저장할 것이기 때문에 빈배열
const dataId = useRef(0);
const getData = async () => {
const res = await fetch(
"https://jsonplaceholder.typicode.com/comments"
).then((res) => res.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(),
id: dataId.current++,
};
});
setData(initData);
};
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; // dataId가 하나씩 증가하도록 만들어줌
setData([newItem, ...data]); // 원래 있던 데이터에 새로운 아이템을 이어서 출력할 수 있음
};
const onRemove = (targetId) => {
console.log(`${targetId}가 삭제되었습니다.`);
const newDiaryList = data.filter((it) => it.id !== targetId);
setData(newDiaryList); // 특정 targetId를 가진 부분만을 제외하고 다시만든 배열은 존달해줌
};
const onEdit = (targetId, newContent) => {
// 특정 데이터를 수정하는 함수
setData(
data.map((it) =>
it.id === targetId ? { ...it, content: newContent } : it
)
);
};
const getDiaryAnalysis = useMemo(() => {
console.log("일기 분석 시작");
const goodCount = data.filter((it) => it.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;
return (
<div className="App">
<DiaryEditor onCreate={onCreate} />
<div>전체 일기 : {data.length}</div>
<div>기분 좋은 일기 개수 : {goodCount}</div>
<div>기분 나쁜 일기 개수 : {badCount}</div>
<div>기분 좋은 일기 비율 :{goodRatio}</div>
<DiaryList onEdit={onEdit} onRemove={onRemove} diaryList={data} />
</div>
);
}
export default App;
// 일기 정보의 길이가 변화할때만, getDiaryAnalysis함수의 값이 반환되고, 이렇게 되면 랜더링의 횟수를 줄이고
최적화를 할 수 있음