Diary 컴포넌트
.... ㄴMyHeader 컴포넌트
: 2개의 MyButton (back, onEdit)과 headText
.... ㄴ article
........ ㄴ section : 오늘의 감정 데이터
........ ㄴ section : 오늘의 일기 내용 데이터
조회(READ)하고자 하는 일기 데이터를 가져올 수 있어야 함
현재 찾으려는 일기 데이터의 id를 구해오는 과정
을 Diary 컴포넌트에도 동일하게 진행id를 기준
으로 찾기중복 사용할 수 있는 공통 코드
가 있다면 별도로 디렉토리를 생성 후 해당 코드를 이동시켜 export해 재사용
공통화
시키기src/util/date.js
export const getStringDate = (date) => {
return date.toISOString().slice(0, 10);
};
src/util/emotion.js
const env = process.env;
env.PUBLIC_URL = env.PUBLIC_URL || "";
export const emotionList = [
{
emotion_id : 1,
emotion_img : process.env.PUBLIC_URL + `/assets/emotion1.png`,
emotion_descript : '완전 좋음'
},
{
emotion_id : 2,
emotion_img : process.env.PUBLIC_URL + `/assets/emotion2.png`,
emotion_descript : '좋음'
},
{
emotion_id : 3,
emotion_img : process.env.PUBLIC_URL + `/assets/emotion3.png`,
emotion_descript : '그럭저럭'
},
{
emotion_id : 4,
emotion_img : process.env.PUBLIC_URL + `/assets/emotion4.png`,
emotion_descript : '나쁨'
},
{
emotion_id : 5,
emotion_img : process.env.PUBLIC_URL + `/assets/emotion5.png`,
emotion_descript : '끔찍함'
},
];
src/pages/Diary.js
import { useContext, useEffect, useState } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { DiaryStateContext } from "../App";
import { getStringDate } from "../util/date";
import { emotionList } from "../util/emotion";
import MyHeader from "./../components/MyHeader";
import MyButton from "./../components/MyButton";
const Diary = () => {
const { id } = useParams(); // pathVariable = id
const diaryList = useContext(DiaryStateContext); // diaryList 가져오기
const navigate = useNavigate(); // 이동
const [data, setData] = useState();
// 데이터는 컴포넌트가 mount된 시점에서 가져온다
// 조건 : 일기데이터가 1개라도 있을 때만 가져온다 (id 오류 방지 형변환)
// deps : id나 diaryList가 변할 때만 가져온다
useEffect(()=>{
if(diaryList.length >= 1) {
const targetDiary = diaryList.find((it)=>parseInt(it.id) === parseInt(id));
console.log(targetDiary); // 가져온 id의 일기데이터 출력
// 현재 상세페이지에서 보여줘야 하는 데이터를 id를 기준으로 찾아온다면
if(targetDiary) { // 일기가 존재할 때
setData(targetDiary);
}
else { // 일기가 없을 때 홈으로 이동
alert("없는 일기 입니다.");
navigate('/', {replace:true});
}
}
},[id, diaryList, navigate]);
// 데이터가 없으면
if(!data) {
return <div className="DiaryPage">로딩중입니다...</div>;
}
// 데이터가 존재하면
else {
// 오늘의 감정 불러오기
const curEmotionData = emotionList.find((it)=>parseInt(it.emotion_id) === parseInt(data.emotion));
console.log(curEmotionData);
return (
<div className="DiaryPage">
{/* header의 조회한 일기 데이터의 날짜를 가져오기 (getStringDate를 받아서 시간객체로) */}
<MyHeader
headText={`${getStringDate(new Date(data.date))} 기록`}
leftChild={<MyButton text={"< 뒤로가기"} onClick={()=>navigate(-1)} />}
rightChild={<MyButton text={"수정하기"} onClick={()=>navigate(`/edit/${data.id}`)} />}
/>
<article>
<section>
<h4>오늘의 감정</h4>
{/* 원본 데이터의 감정 가져오기 */}
<div className={["diaryImgWrapper", `diaryImgWrapper${data.emotion}`].join(" ")}>
<img src={curEmotionData.emotion_img} alt={`${curEmotionData.emotion_descript}`} />
<span className="emotionDesc">{curEmotionData.emotion_descript}</span>
</div>
</section>
<section>
<h4>오늘의 일기</h4>
{/* 원본 데이터의 일기 내용 가져오기 */}
<div className="diaryContentWrapper">
<p>{data.content}</p>
</div>
</section>
</article>
</div>
);
}
}
export default Diary;
/* Diary */
.DiaryPage { text-align:center; }
.DiaryPage section { width:100%;display:flex;flex-direction:column;align-items:center;text-align:center; }
.DiaryPage h4 { padding:24px 0 16px;font-size:22px;font-weight:600; }
.DiaryPage .diaryImgWrapper { width:250px;height:250px;border-radius:5px;display:flex;flex-direction:column;align-items:center;justify-content:space-around;background-color:#ececec; }
.DiaryPage .diaryImgWrapper1 { background-color:#64c964;color:#fff; }
.DiaryPage .diaryImgWrapper2 { background-color:#9dd772;color:#fff; }
.DiaryPage .diaryImgWrapper3 { background-color:#fdce17;color:#fff; }
.DiaryPage .diaryImgWrapper4 { background-color:#fd8446;color:#fff; }
.DiaryPage .diaryImgWrapper5 { background-color:#fd565f;color:#fff; }
.DiaryPage .diaryImgWrapper .emotionDesc { display:block;font-size:20px; }
/* Diary Content */
.DiaryPage .diaryContentWrapper { width:100%;background-color:#ececec;border-radius:5px;word-break:keep-all;overflow-wrap:break-word; }
.DiaryPage .diaryContentWrapper p { padding:16px 20px;text-align:left;font-family:'Yeon Sung', cursive;font-size:18px;font-weight:400;line-height:1.4; }
💬 CRUD
구현 완성 (하하하 😁) 실전편은 앞 챕터의 기본편의 반복/업그레이드로 이루어져 있는데, 사소하지만 이런 과정을 통해 JavaScript의 Method나 왜 이 React Hooks이 쓰이게 되는지 자연스럽게 학습할 수 있다(!)
💬 Problems에 뭔가가 뜬다면 ESLint 꼭 체킹하기