[ 인프런 - 한입 크기로 잘라 먹는 React] 3. React 실전 프로젝트 - 감정 일기장 만들기(4)
인프런 이정한님의 한입크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지 ] 강의 수강 후 강의의 내용을 정리하며 공부한 것을 쓴 게시글입니다.
한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지 - 인프런 | 강의
개념부터 독특한 프로젝트까지 함께 다뤄보며 자바스크립트와 리액트를 이 강의로 한 번에 끝내요. 학습은 짧게, 응용은 길게 17시간 분량의 All-in-one 강의!, - 강의 소개 | 인프런...
www.inflearn.com
삭제 기능 구현
- 일기 아이템 클릭 후 수정하기 페이지에서 삭제 기능 구현
- 추후 홈 화면에서도 삭제 가능하도록 구현할 예정
- diaryEditor의 헤더의 rightChild에 삭제 버튼 추가
- 새 일기 쓸 때에는 삭제 기능이 구현되면 안되므로 isEdit이 참일 때만 버튼 보이게 함
rightChild={
isEdit && (<MyButton text={"삭제"} type={"negative"} onClick={handleRemove}/>)
}
- onClick 함수인 handleRemove 함수 정의
const handleRemove = () => {
if (window.confirm("일기를 삭제할까요?")) {
onRemove(originData.id);
navigate("/", { replace: true });
}
};
LocalStorage 사용하기
LocalStorage 사용 예제
- LocalStorage에 데이터 저장하기
- localStorage.setItem("key", value);
- 객체 그대로를 전달하면 원하는 대로 값이 전달되지 않으므로, JSON의 stringify함수를 이용해서 객체를 저장
localStorage.setItem("item1", 10);
localStorage.setItem("item2", "10");
localStorage.setItem("item3", { value: 30 });
localStorage.setItem("item4", JSON.stringify({ value: 30 }));
- LocalStorage의 데이터 가져오기
- key값으로 데이터를 가져올 수 있음
- const item = localStorage.getItem("key");
const item1 = localStorage.getItem("item1");
const item2 = localStorage.getItem("item2");
const item3 = localStorage.getItem("item3");
const item4 = localStorage.getItem("item4");
- 정수를 저장해도 가져올 때는 문자열 형태로 가져오게 됨
- JSON으로 저장한 객체 타입도 문자열 형태로 가져오게 됨
- 정수형 그대로 가져오려면 parseInt 써야하고, 객체를 그대로 가져오려면 JSON.parse 써야 함
const item1 = parseInt(localStorage.getItem("item1"));
const item2 = localStorage.getItem("item2");
const item3 = localStorage.getItem("item3");
const item4 = JSON.parse(localStorage.getItem("item4"));
LocalStorage에 Diary 저장하기
- app.js의 reducer 함수에 newState를 key값을 diary로 하여 localStorage에 저장
localStorage.setItem("diary", JSON.stringify(newState));
LocalStorage에서 Diary 가져오기
- 컴포넌트가 mount 될 때 실행되도록 useEffect 사용
- key값인 diary로 getItem해서 localData에 저장
- localData가 있고, 길이가 0보다 클 때만 가져온 값을 diaryList에 저장
- 현재 데이터들의 아이디 값을 내림차순으로 정렬했을 때, 아이디가 가장 큰 값인 첫번째 요소의 아이디값에 1을 추가한 것을 그 다음 추가될 요소의 아이디인 dataId로 지정함
- dispatch함수에 type을 INIT으로 하여 dairyList를 저장
const [data, dispatch] = useReducer(reducer, []);
useEffect(() => {
const localData = localStorage.getItem("diary");
if (localData && JSON.parse(localData).length > 0) {
const diaryList = JSON.parse(localData).sort(
(a, b) => parseInt(a.id) - parseInt(b.id)
);
console.log(diaryList);
dataId.current = parseInt(diaryList[0].id) + 1;
dispatch({ type: "INIT", data: diaryList });
}
}, []);
프로젝트 최적화하기
문제점1. 월 이동시마다 ControlMenu가 리렌더링 됨
-> ConrolMenu 함수를 React.memo로 감싸줌
const ControlMenu = React.memo(({ value, onChange, optionList }) => {
return (
<select className="ControlMenu" value={value} onChange={(e) => onChange(e.target.value)}>
{optionList.map((it, idx) => (
<option key={idx} value={it.value}>{it.name}</option>
))}
</select>
);
문제점2. ConrolMenu 변경할때마다 (최신순/오래된 순 변경) DiaryItem들이 리렌더링 됨
-> DiaryItem을 export할 때 React.memo로 감싸줌
export default React.memo(DiaryItem);
문제점3. 일기의 내용 수정할때마다 그 위에 있는 EmotionItem들이 리렌더링 됨
-> EmotionItem을 export할 때 React.memo로 감싸줌
-> handleClickEmotion함수를 useCallback으로 감싸줌
export default React.memo(EmotionItem);
const handleClickEmotion = useCallback((emotion) => {
setEmotion(emotion);
}, []);
배포 준비 & 프로젝트 빌드하기
icon 변경하기
- 무료 다이어리 아이콘 png 파일을 다운받고, ico 파일로 변경함
title 변경하기
- title 태그를 받아와서 innerHTML을 변경해주면 된다.
- 다이어리 상세보기 페이지에서는 해당 일기의 날짜를 title에 반영하고 싶어서 아래와 같이 코드를 썼다.
useEffect(() => {
const titleElement = document.getElementsByTagName("title")[0];
titleElement.innerHTML = `Emotion Dairy`;
});
if (targetDiary) {
setData(targetDiary);
const titleElement = document.getElementsByTagName("title")[0];
titleElement.innerHTML = `${moment(targetDiary.date).format(
"MM월 DD일 dddd"
)} - Emotion Dairy`;
}
빌드하기
- 빌드 명령어 (cmd)
$ npm run build $ npm install -g serve (serve 설치 안되어 있다면) $ serve -s build |
- 아래와 같이 뜨면 빌드 완료
- 만약 오류를 발견해 수정이 필요하면 수정 후 위 명령어를 다시 입력
- npm start를 하지 않아도 아래 주소에 접속 가능
- Network에 있는 주소는 현재 내 pc와 같은 네트워크와 연결되어 있는 곳에서 접속 가능
Firebase로 프로젝트 배포하기
Firebase
Firebase는 고품질 앱을 빠르게 개발하고 비즈니스를 성장시키는 데 도움이 되는 Google의 모바일 플랫폼입니다.
firebase.google.com
1. 파이어베이스 접속해 로그인
2. 메인 화면에서 시작하기 클릭
3. 프로젝트 추가 클릭
4. 프로젝트 이름을 입력하고 '계속' 버튼 클릭
5. 이 프로젝트에서 Google 애널리틱스 사용 설정 체크 해제하고, (필요시 체크) 프로젝트 시작 버튼 클릭
6. 왼쪽 메뉴에서 빌드 - 호스팅 - 시작하기
7. cmd에서 $ npm install -g firebase-tools입력
8. vs코드의 루트 프로젝트 폴더 로 가서 cmd터미널에서 $ firebase login 입력
9. y입력하고, 계정 선택하면 로그인 성공 창 팝업됨
9. $ firebase init 입력
10. y입력 -> Hosting 선택 -> Use an existing project 선택 -> 프로젝트 선택 -> build 입력 -> y입력 -> 깃허브 사용 시 y입력 -> y입력
11. 파이어베이스 사이트로 다시 들어와서 콘솔로 이동 버튼 클릭
12. 맨 아래로 내려가서 고급 - 다른 사이트 추가 - 만들고자 하는 페이지 url 지정
13. firebase.json 파일에서 "hosting" 안 "site" 지정해줌
14. 다시 $npm run build
15. $ firebase deploy
16. 접속 가능
- 썸네일 이미지, 사이트 이름, 사이트 설명 설정하기
- 아래코드를 index.html 파일에 쓴다.
<meta property="og:image" content="%PUBLIC_URL%/thumbnail.png" />
<meta property="og:site_name" content="Emotion Dairy" />
<meta property="og:description" content="What's your today emotion?" />
- $ npm run build
- $ firebase depoly
- 이전에 한 번 공유하고, 다시 공유한다면, 카카오톡에서 공유했을 때, 바뀐 것들이 적용되지 않는다.
Kakao Developers
카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.
developers.kakao.com
- 도구 - 디버거 도구 - 공유 디버거 - url 입력창에 url 입력 후 캐시 초기화 클릭
- 아래와 같이 썸네일과 설명, 사이트 이름이 잘 적용되었다.
- 나중에 기능을 더 추가하여 디자인 된 썸네일을 다시 등록할 예정이다.
Emotion Diary
What's your today emotion?
cjy00n-emotion-diary.web.app