한 입 크기로 잘라먹는 리액트 마무리

이안이다·2023년 6월 30일
0

React

목록 보기
7/7

7강에서 버그 수정하기 전까지 강의를 수강해놓고, 기말고사와 해커톤 대회 운영을 한다고 잠시 쉬었다가 왔다. 2주 정도 안했다고 진짜 하나도 기억이 안나는 것 같은 기분이지만,, 다행히 정리해뒀던 벨로그 글들을 훑어보니 기억이 도움이 된다. 이번 시간에는 만들었던 감성일기장을 최적화하고 가다듬어서 배포해서 이 강좌를 마무리하는 것을 목표로 마지막 한입크기 리액트 포스팅을 해보겠다. 아자아자!!!


일기쓰기


이슈 1. 레이아웃이 내가 의도한대로 가로배열이 안됐다.
이슈 2. 일기 작성 시 감정을 선택하면 무엇을 선택했는지 알 수가 없다.

.EmotionItem {
  cursor: pointer;

  border-radius: 5px;
  padding-top: 20px;
  padding-bottom: 20px;

  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

App.css에 위와 같은 클래스를 만들어서 넣어줬다.
여기서 flex-direction을 column으로 지정한 것이 처음에는 이해가 안됐다. 세로로 정렬돼있는 저 셀렉터들을 가로로 나열하고 싶은건데 왜 column으로 넣으라는건지 이해가 안됐지만 이번에도 역시나 내가 멍청했다,,

감정img와 아래에 '완전좋음'을 세로로 유지하기 위해서 플렉스 방향을 column으로 뒀다.

.DiaryEditor .emotion_list_wrapper {
  display: grid;
  grid-template-columns: repeat(5, auto);
  gap: 2%;
}

그리고 grid 레이아웃을 사용해서 원하던 가로 정렬을 구현할거다. 노마드코더 코코아톡 챌린지 때부터 flexbox는 익숙하게 다뤄와서 익숙했는데 그리드는 처음 써봤다. 근데 뭔가 훨씬 직관적이고 익숙해지기만 하면 더 편할 것 같은 느낌..?

gird-template-colums

gird-template-columns: repeat(5, auto); 를 보자.

가로로 그리드 다섯개를 정렬할거고, 다섯개의 열을 나열하고 그 아이템들의 사이즈는 자동으로 조정해라! 그리고 아이템과 아이템 사이의 gap은 2%로 하겠다! 라는 뜻이다.

그리고 이슈 1번을 해결하기 위해서, 내가 선택한 감정이 뭔지 알 수 있어야 하기 때문에 EmotionItem.js파일을 만들어서 prop을 이용해서 내가 선택한 아이템에는 true를, 선택받지 않은 녀석들은 false로 넣어두게끔 해두자. 아래에 js, css둘다 코드 첨부하겠음.

import React from "react";

const EmotionItem = ({
  emotion_id,
  emotion_img,
  emotion_descript,
  onClick,
  isSelected,
}) => {
  return (
    <div
      onClick={() => onClick(emotion_id)}
      className={[
        "EmotionItem",
        isSelected ? `EmotionItem_on_${emotion_id}` : `EmotionItem_off`,
      ].join(" ")}
    >
      <img src={emotion_img} />
      <span>{emotion_descript}</span>
    </div>
  );
};

export default React.memo(EmotionItem);

이렇게 리액트 만들어놓고 내가 선택한 감정은 그 아이템 박스 전체가 그 감정색깔과 똑같이 채워지게끔 만들어보자.

.EmotionItem_off {
  background-color: #ececec;
}

.EmotionItem_on_1 {
  background-color: #64c964;
  color: white;
}

.EmotionItem_on_2 {
  background-color: #9dd772;
  color: white;
}
.EmotionItem_on_3 {
  background-color: #fdce17;
  color: white;
}
.EmotionItem_on_4 {
  background-color: #fd8446;
  color: white;
}
.EmotionItem_on_5 {
  background-color: #fd565f;
  color: white;
}


짜라란 ~ 내가 만지는 것들이 하나씩 바로바로 눈에 보이니까 좀 재미가 붙는듯하다.


일기 수정하기

일단 Edit.js파일을 아래와 같이 완성했당.

import { useState, useContext, useEffect } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { DiaryStateContext } from "../App";
import DiaryEditor from "../components/DiaryEditor";

const Edit = () => {
  const [originData, setOriginData] = useState();
  const navigate = useNavigate();
  const { id } = useParams();

  const diaryList = useContext(DiaryStateContext);

  useEffect(() => {
    const titleElement = document.getElementsByTagName("title")[0];
    titleElement.innerHTML = `감정 일기장 - ${id}번 일기 수정`;
  }, [id]);

  useEffect(() => {
    if (diaryList.length >= 1) {
      const targetDiary = diaryList.find(
        (it) => parseInt(it.id) === parseInt(id)
      );

      if (targetDiary) {
        setOriginData(targetDiary);
      } else {
        alert("없는 일기입니다.");
        navigate("/", { replace: true });
      }
    }
  }, [id, diaryList, navigate]);

  return (
    <div>
      {originData && <DiaryEditor isEdit={true} originData={originData} />}
    </div>
  );
};

export default Edit;

솔직하게 여기 완벽히는 이해 안 된다.
DiaryList에서 useParams()로 받아온 저 {id}라는 일기 데이터 값을 하나씩 꺼내오는 원리이다. useEffect()를 써서 가져올거고, id나 diaryList가 변했을 때마다 다른 데이터 값을 꺼내와야 하기 때문에 이 부분도 같이 처리해준다. edit 컴포넌트가 마운트 됐을 때 동작한다는 거 정도 기억 하고 넘어갈래...

const targetDiary = diaryList.find(
        (it) => parseInt(it.id) === parseInt(id)

그리고 이 부분. 내가 꺼내온 id의 data값이 문자열인지 숫자형인지 알 수 없는데 만약 다르다면 충돌이 발생할 수도 있기 때문에 아싸리 둘 다 parstInt씌워서 정수로만 만들어뒀다.

자 이 부분에서 날짜를 내가 이 일기장을 보고 있는 그 날을 디폴트로 미리 잡아두기 위해서 다음과 같이 코드를 추가했다.

  useEffect(() => {
    if (isEdit) {
      setDate(getStringDate(new Date(parseInt(originData.date))));
      setEmotion(originData.emotion);
      setContent(originData.content);
    }
  }, [isEdit, originData]);

이렇게 추가해주면 의도한대로 된다. 그리고 지금 가다듬고 있는 '수정하기'페이지에서도 적용돼서 내가 과거의 일기를 수정하면 과거의 일기가 아닌 현재의 날짜를 기준으로 다시 날짜 정보도 업데이트 할 수 있게 된다.


배포


자 이제 진짜 마지막 배포 단계!


이렇게 npm run build 명령어를 입력해주면 뭐라뭐라 하다가

이렇게 빌드를 위한 폴더가 준비되었다는 문구가 뜬다. 규모가 크지 않았는데도 나는 40초 정도는 기다렸던 것 같다. 프로젝트의 규모가 클수록 이 과정의 시간이 더 오래 소모된다고 한다.

그러면 이제

이렇게 npm install -g serve 명령해주고
마지막으로 serve -s build를 명령해주면 !?!?!?


젠장 이게 뭔 ,,, ?

serve : 이 시스템에서 스크립트를 실행할 수 없으므로 C:\Users\iank1\AppData\Roaming\npm\serve.ps1 파일을 로드할 수 없습니다. 자세한 내용은 about_Execution_Policies(https://go.microsoft.com/fwlink/?LinkID=135170)를
참조하십시오.
위치 줄:1 문자:1

  • serve -s build
  •   + CategoryInfo          : 보안 오류: (:) [], PSSecurityException
      + FullyQualifiedErrorId : UnauthorizedAccess

라는 에러가 떠서 포기하고 자고나서 하려고 했지만

우리 희건이가 해결해줬다. 저대로 하고 Y/N에서 Y만 입력하고나서 다시 터미널로 와서 실행했더니 잘 된다.

참고로 ctrl+c를 누르면 shut down이 된다. 얘는 코드를 수정하고 저장한 다음 localhost3000을 새로고침 한다고 변경사항이 적용되지 않는다. 변경된 사항이 있다면 빌드를 셧다운하고 다시 빌드해서 배포해야 한다는 점 기억하장.


Firebase를 사용해서 찐배포를 시작해보자 !

둥둥...둥둥.....둥둥두웅....

cmd를 관리자 권한으로 실행해서

이렇게 firebase에서 알려준 명령어를 치면 한참동안 뭔가가 설치가 된다.

...

혹시나 따라가다가 하나라도 놓치면 꼬일까봐 조마조마 하면서 윈터루드 형의 가이드를 따라서 배포까지 성공했다 !!
(https://ian-react-project-emotiondiary.web.app/)
이 주소로 들어가면 내가 열심히 만든 갬성 일기장이 등장한다!


자 이제 진짜 찐막! 오픈그래프 설정만 하면 된다.


이랬던걸

이렇게까지는 만들었는데 이미지가 안들어간다 !!
문제는 역시 경로였다. 썸네일로 띄우고 싶은 이미지를 public폴더에 넣었어야 했는데 그거보다 하나 하위폴더에 넣어놔서 안됐던 것이다.

왜냐하면

    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta name="description" content="나만의 감정 일기장" />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />

    <meta property="og:image" content="%PUBLIC_URL%/thumbnail.png" />
    <meta property="og:site_name" content="갬성 일기장" />
    <meta property="og:description" content="나 김이안이 직접 만든 갬성 일기장" />

여기서 보이는 것 처럼 %퍼블릭 URL을 쓰고 있는데 저 퍼센트는 경로를 public으로 보내서 그 안에 있는 다음 ~~파일을 읽어오겠다는 뜻이기 때문! 이미지 파일의 위치만 옮겼다고 하더라도 엄연한 코드 수정이니까 다시 빌드해서 배포까지 해보자.

npm run build
firebase deploy

지겹도록 치고 있는 두 명령어 ....


하하~ 완성했다.


마치며

일단 리액트! 만만하지 않았다. 함께 반학기 동안 함께 스터디한 우리 TAB 웹 스터디 팀(한림,지민,이산드라,서연,희건,성준 그리고 혜진) 덕분에 김 빠지지 않고 꾸준히 열정적으로 따라올 수 있었던 것 같다. 어려웠고 솔직히 따라서 만든 지금도 다시 혼자 만들라면 절대 못 만들 것 같지만 리액트가 어떤 원리와 기능들을 기반으로 동작하는지, 어떻게 써먹을 수 있는지 또 내가 만든 웹을 어떻게 배포할 수 있고 어떻게 수정할 수 있는지, 링크 썸네일(OG)도 어떻게 수정하고 만질 수 있는지는 명확하게 이해하고 배울 수 있는 시간이었다.

다른 분야에 대한 공부보다는 한 김에 리액트를 조금 더 공부해보고 싶고 이거로 프로젝트를 하나 더 해보고 싶다는 생각도 든다. 아무튼 뿌듯하다 ! 이상.

profile
경제와 개발을 곁들인 기획자..!

0개의 댓글