=> 즉 컴퓨터 프로그램이 동일 계산 반복해야할때, 이전에 계산한 값을 메모리에 저장해서 반복 수행 제거하여 프로그램 수행속도 빠르게 하는것!
코드에서 데이터가 20개로 잘려서 다시 setData를 호출하면서, 데이터가 바뀌고, app 컴포넌트가 리랜더됨-> 안 코드 재생성되면서 두번 실행하는것임
=> 호출할때는 함수가 아니라, 변수만 호출하면 되는것임!!
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;