[JUSTCODE] 1차 프로젝트 후기 👋🏻HALLO!

Eden·2022년 9월 15일
0

myPlace

목록 보기
3/23
post-thumbnail

✅ 프로젝트 소개

Hola!

우리 팀이 1차 프로젝트로 클론코딩을 진행한 사이트는 Hola!다. Hola!는 개발 관련 스터디, 프로젝트 동료 구하는 사이트로 기술 스택 별로 게시글을 보여주며, 사용자가 글을 작성 및 댓글을 남겨 원하는 팀원을 찾을 수 있는 사이트다.

해당 사이트를 클론하기로 한 이유
e-commerce 사이트의 경우 사진 사용에서 저작권에 자유롭지 못한 점과 조회에 관련된 기능들이 메인으로 조회 기능에 치우쳐서 프로젝트를 진행하기보다는 밸런스 있게 게시판(CRUD) 형식의 사이트를 경험하고자 선정하였다. 또한 부트 캠프를 들어와서 처음 시작하는 프로젝트인 만큼 다양한 기능을 진행해 보는 것보다는 완성도에 목표를 두고 싶었다.

진행기간

2022/08/29 - 2022/09/8 약 10일간의 프로젝트

팀 구성

JUSTCODE 6기
FE : 4명
BE : 2명

기술 스택

Front-End : Javascript, React.js, sass, slick, react-modal, create portal
Back-End : Node.js, express, Bcrypt, JWT, RESTful API
Communication : slack, Notion, zep

구현 기능

회원가입 페이지
로그인 페이지
사용자 정보 페이지
헤더 & 푸터
메인 페이지(기술 스택 리스트, 게시글 목록 읽어오기)
게시글 작성
상세페이지 (게시글 수정 & 삭제, 댓글 읽어오기, 댓글 작성, 댓글 수정 & 삭제)

👋🏻 내가 맡은 역할!

게시글 상세페이지

  • 게시글 상세페이지 UI.
  • 게시글 페이지에서 뒤로가기, 게시글 수정 페이지 이동, 게시글 삭제 기능 구현.
  • 게시글 GET, 게시글 DELETE API 연동.
  • 댓글 리스트 UI.
  • 새 댓글 작성 기능 구현. (로그인한 작성자만 가능)
  • 댓글 삭제 기능, 댓글 수정 기능 구현. (댓글 작성자만 가능)
  • 사용자 정보 GET, 댓글 GET, POST, DELETE, PATCH API연동

Modal

  • 재사용 가능한 모달 창 UI 구성

컴포넌트 구성

  • Post.js : 게시글 상세페이지
  • Comment.js : 댓글 목록
  • NewComment.js : 댓글 리스트 업, 댓글 수정, 댓글 삭제
  • Modal.js : 게시글 삭제 모달, 댓글 삭제 모달

✅ 프로젝트 진행과정

Planning meeting!

① 구현 기능 파악 및 계획 그리고 분배

첫번째로 모인 미팅에서 팀명을 정한 후에 클론코딩할 사이트를 정하고나서 프론트와 백에서 각각 구현해야할 것을 정리하고 다시 만나기로 했다.

오후 planning meeting 에서 프론트엔드 포지션인 나와 팀원들의 파악한 기능은 위와 같았고 심사숙고 끝에 각자 맡을 파트를 분배했다. 백엔드 팀원들도 서로 얘기를 나눈 후에 파트를 분배했다!

② 칸반보드 티켓 관리

Not started In progress Completed로 분류하고 각자 해야할 업무를 티켓으로 정리했다. 처음에는 어떻게 티켓을 구분해서 사용해야할 지 잘 몰랐지만 프로젝트를 진행하다 보니 감이 잡혀 적극적으로 사용했다. 한 눈에 티켓이 보이니 나와 팀원들의 진행상황이 어디쯤인지 파악할 수 있어 유용했다.

Daily meeting

우리 팀의 데일리 미팅은 매일 오전 11시 진행되었고, 실제 구현한 페이지를 공유하면서 진행사항을 보고하고 금일 진행할 사항에 대해 공유하는 식으로 진행했다. 그 과정에서 질의응답과 서로에 대한 피드백이 이루어지기도 했다. 가끔씩 오후 7시에 데일리 스탠드 업 미팅을 진행해 서로 막히는 부분이 있거나 의논해야하는 사항이 있으면 공유하기도 했다.
그런데 사실 대부분의 팀원들이 zep에 상주해 있어 수시로 소통할 수 있어서 프로젝트를 진행할 때 엄청 수월했다!

프론트-백 소통

프로젝트 초반에 프론트엔드 나를 포함한 팀원들은 레이아웃을 만드는 동안 백엔드 팀원들은 데이터 모델링을 진행했다. 개인적으로는 처음에 백엔드에 대한 이해가 부족해서 코드를 작성할 때 어려움이 있었는데 API명세서도 자세히 적어주시고 zep에 매일 상주해있는 백엔드 팀원이랑 적극적으로 소통을 진행하다보니 어느새 퍼즐이 맞춰져가고 있었다!

✅ 프로젝트를 통해 얻은 것

협업

프로젝트 시작 전에 내가 만든 저스트그램에 백엔드 동기가 만든 서버에 연결하는 잠깐의 시간이 있기도 했지만 지금의 프로젝트가 나의 첫 협업 프로젝트였다! 같은 프론트엔드 팀원 분들과도 물론 백엔드 팀원들과 팀을 이뤄 프로젝트를 진행한다는 것이 너무 신기하고 설렜다. 진짜 개발자가 된 기분 🤩🤩!
그렇지만 이전에 혼자 진행했을 때보다 부담되기도 했다. 팀 프로젝트에서는 역할 분담도 해야하고, 컨벤션도 통일해야하고, git 같이 관리도 해야하기 때문에 더욱 책임감을 가지고 임하게 되었다. 하지만 그렇게 모든 과정을 겪으며 고생을 하다보니 우린 원팀이 되었다 🥇
먼저 생각보다 백엔드와 교류를 많이 해야 했다. 데이터를 어떤 형태로 받아와야하는지, 어떤 정보들을 요청할 수 있는지,, 이 과정에서 내가 해야할 일과 백엔드에서 해주어야하는 일이 잘 구분이 되지 않아 코드 짜는 데에 많이 고생했던 것 같다. 통신을 한 뒤에는 "서버 열어주세요!!!!" "서버 주소 다시 주세요ㅠㅠ" 라는 말을 입에 달고 살아야했다. (정말 감사합니다..ㅎㅎ) 고생은 많았지만 API 연동하면서 부터 정말 뿌듯했다. 이게 정말 된다고? 나도 할 수 있구나... 하면서 앞으로 가는 길에 용기를 얻을 수 있었던 팀플이었다!
정말 정말 좋았던 것은 모든 팀원들의 참여도가 높았고, 모르는 것이 있으면 다들 열심히 알려주려고 하고 같이 고민을 해주기도 했다. 첫 협업의 과정이 너무 감동적이어서 정말 눈물날뻔했다..🥹

mindset

프로젝트 시작 전에 내 실력에 대한 불안감과 자바스크립트에 대한 막연한 두려움이 있었다. 프로젝트 진행하면서 팀에 민폐를 끼치게 되지 않을까 걱정도 했지만, 맨땅에 헤딩이라는 말이 괜히 있는게 아니다. 부트캠프 기간 내내 내 실력은 객관적으로 99%라는 생각을 지울 수 없었는데, 일단 허허벌판에 던져지고 보니 어떻게든 하고 있는 나를 발견했다. 프로젝트 전에는 뭘 모르는지 몰라서 질문도 잘 못했는데 무작정 세션참고하고 구글링해가면서 코드를 작성해보니 돌아가긴 한다. 개발에 있어서 중요한 것은 마음가짐이다.

✅ 프로젝트를 통해 느낀 점

잘한 점

모르는 것이 있으면 질문하기!
일단 잘난 팀원들을 만난 것이 첫번째로 잘한 것이고,, 두번째는 멋있는 팀원들을 잘 이용(?)했다는 점이다. 난 사실 질문하는 것 자체가 부끄러워서 잘 못했었는데 나의 이런 부분은 개발 인생에 별로 도움이 되지 않을 것 같았다. 팀플이기도 하고, 나도 변화할 필요성을 느껴서 일부러 질문을 많이 했다. 전공자, 현업에서 온 팀원들이 많아서 구글 선생님만큼이나 잘 알려주고 도와주셨다!

코드 리팩토링
시간상 간단하게 구현한 사항이 몇군데 있어서 아쉬웠는데, 주말내내 리팩토링을 진행해보았다. 내 코드가 어떻게 생겼는지를 떠나 시도 자체를 잘한 것 같다.

아쉬운 점

git
깃에 대한 지식이 부족해서 깃 사용법과 팀 레포를 관리하는 법에 감이 전혀 오지 않았다.
처음에 각자의 이름으로 생성한 브랜치로 저장하다가 기능별로 브랜치를 관리하는 과정에서 conflict가 나고 그 과정에서 파일이 사라졌는데 되돌릴 수도 없어서 다시 코드를 처음부터 만져야했다. 깃 미니세션을 통해 깃 관리방법과 중요함을 깨달았고, 우리팀 팀장님의 미니세션 속의 세션을 통해 깃과 조금 친해질 수 있었다. 코딩하는 것을 배우는 것 만큼 깃도 중요한데 지금까지 잘 알지 못했다는 데에서 아쉬운 점이 있었다. 다음 프로젝트 아니 앞으로를 위해선 충분한 git 공부가 필요하다.

API연동 그리고 코드 구성하는 것.
처음에 하드코딩으로 레이아웃과 구성과 기능을 구현했는데, API 통신을 하려고 보니 컴포넌트 2개의 코드를 아예 처음부터 구성을 해야했다. 허탈했다. 시간에 쫓길까봐 초반에 급하게 프로젝트를 시작한 감이 없지 않아 있었고, 백에 대한 이해가 부족했다보니 DB를 구성하는 것과 API를 연동할 때를 생각을 못하고 코드를 구성했었다. 팀원들에게 질문해가며 코드를 다시 짜면서 느낀 점은 앞으로는 생기지 않을 문제라는 것이다. 이번 프로젝트는 처음이니까 잘 몰랐던 거고 프로젝트를 통해 하나 배운 거다!

useEffect 사용 & 랜더링 시점
mock 데이터를 연동했을 때 기능 구현은 완벽하게 되었다고 생각했지만 API 연동 후 백엔드 팀원의 서버에서 무한 랜더링되는 현상이 발생되었다. 댓글이 업데이트 되었을 때, 게시글이 업데이트 되었을 때, 처음 한 번만 실행.. 등등 시점을 변경 해보았지만 원하는 지점을 찾을 수 없어서 시간을 많이 잡아먹었다. 해결 방법은 댓글목록 가져오는 api연동을 함수로 선언해주고 댓글목록 가져오기, 등록, 수정, 삭제할 때에 그 함수를 호출해주는 것으로 해결할 수 있었다.

✅ 기록하고 싶은 코드

comment.js
------------------------------------------------------
 //댓글 GET
  const loader = () => {
    fetch(`http://localhost:8000/comment/${postId}`)
      .then(res => res.json())
      .then(data => {
        setCommentArray(data?.comments ?? []);
      });
  };

  useEffect(() => {
    loader();
  }, []);

  // 댓글 POST
  const addComment = () => {
    const token = localStorage.getItem(LOGIN_TOKEN);

    if (!token) {
      alert('로그인 후 이용해주세요');
      return;
    }

    const body = {
      comment,
    };

    fetch(`http://localhost:8000/comment/${postId}`, {
      method: 'POST',
      headers: {
        token: token,
        'Content-type': 'application/json',
      },
      body: JSON.stringify(body),
    })
      .then(res => res.json())
      .then(res => {
        loader();
      });
    setComment('');
  };

  // 댓글 DELETE
  const deleteComment = (id, user) => {
    const token = localStorage.getItem(LOGIN_TOKEN);

    if (!token) {
      alert('로그인 후 이용해주세요');
      return;
    }

    if (userInfo !== user) {
      alert('작성자 정보와 다릅니다.');
      return;
    }

    fetch(`http://localhost:8000/comment/${id}`, {
      method: 'DELETE',
      headers: {
        token: token,
        'Content-type': 'application/json',
      },
    })
      .then(res => res.status)
      .then(data => {
        loader();
      });
  };

  // 댓글 PATCH
  const modifyComment = (id, body) => {
    const token = localStorage.getItem(LOGIN_TOKEN);

    if (!token) {
      alert('로그인 후 이용해주세요');
      return;
    }

    if (userInfo !== body.user) {
      alert('작성자 정보와 다릅니다.');
      return;
    }

    fetch(`http://localhost:8000/comment/${id}`, {
      method: 'PATCH',
      headers: {
        token: token,
        'Content-type': 'application/json',
      },
      body: JSON.stringify({
        comment: body.comment,
      }),
    })
      .then(res => res.json())
      .then(res => {
        loader();
      });
  };
modal.js
----------------------------------------------------------------
import React from 'react';
import styles from './Modal.module.scss';

function Modal({ visible, text, cancelText, onClose, confirmText, onConfirm }) {
  if (!visible) return null;
  return (
    <>
      <div className={styles.modalBackground} />
      <div className={styles.modal}>
        <div className={styles.modalWrapper}>
          <div className={styles.modalDelete}>
            <p>{text}</p>
            <div className={styles.modalButton}>
              <button className={styles.cancelButton} onClick={onClose}>
                {cancelText}
              </button>
              <button className={styles.deleteButton} onClick={onConfirm}>
                {confirmText}
              </button>
            </div>
          </div>
        </div>
      </div>
    </>
  );
}

export default Modal;

모달 창을 재사용할 수 있게 만들었다.

✅ 완성모습

🎥 프로젝트 시연 영상

✅ 마치며

이미 익숙한 것들을 새로운 시각으로 볼 수 있게 된다는 것 참으로 커다란 축복인 것 같다. 제자리에 머물러 있어도 정체되지 않게끔 하는 것. 그게 바로 배움의 힘이겠지. 모든 배움은 다 쓸모가 있다는 걸 다시금 깨달았다. 열심히 하자 😎

profile
one part.

0개의 댓글