[Watcha Classic] 프로젝트 회고록

Joah·2022년 7월 3일
1

프로젝트-Watcha Classic

목록 보기
15/15
post-thumbnail

1차 프로젝트 Watcha Classic 회고록


⛳ 프로젝트 준비

📍 반가운 왓챠피디아
📍 리액트 복습
📍 담당한 페이지 분석


📍 반가운 왓챠피디아

팀원들과 공통점이 있다면 모두 영화광이라는 것이다.
2주 동안 구현하는 서비스가 영화 백과사전이라면 힘들어도 재미있게 할 수 있겠다고 입을 모아 말했다.

왓챠피디아의 새로운 이름, 고전 영화 백과사전 Watcha Classic 프로젝트를 시작했다.

📍 리액트 복습

프로젝트를 시작하기 2주 전, 처음 React를 접했다. 리액트로 진행하는 프로젝트에서 다른 팀원에게 피해를 주지 않고 온전히 나의 몫을 다 해내려면 최소 State와 props, component에 대한 지식이 숙지가 아닌 숙달이 되어 있어야 했다. 그러기 위해서 이해가 될 때까지 반복 학습을 진행했다.
역시 Practice makes improvement!!

📍 담당한 페이지 분석

» 메인 페이지

  • 메인 페이지는 깔끔한 UI로 사용자에게 전달할 정보만 보인다.

  • 버튼을 누르면 영화 목록이 슬라이드 되며 버튼이 사라지고 나타난다.

  • 영화 목록을 클릭하면 영화 상세페이지로 이동한다.

  • 영화 포스터 아래 영화에 대한 정보가 나열되어 있으며 포스터와 마찬가지로 영화 정보를 클릭하여도 영화 상세페이지로 이동한다.


» 보고싶어요 페이지

  • 커머스 서비스로 비교하자면 장바구니 기능과 동일하다.

  • 메인 페이지와 비슷한 구조로 되어 있다.

  • [보고싶어요] 기능이 선행되어야 한다.


» Footer

  • 사이트 모든 페이지 하단에 위치한다.

  • 자주 바뀌지 않을 데이터라 가정하고 상수 데이터로 작성한다.



⛳ 프로젝트 진행

📍 구현 내용
📍 Errors & Blockers


📍 구현 내용

이미지 슬라이드 구현 과정

3개의 fetch 함수로 데이터 가져오기 (Query Parameter )

서버에서 데이터 가져오기 구현 과정

영화 목록 클릭 시 영화 상세 페이지로 이동하기 (Path Parameter)

각 영화에 따른 상세페이지 이동 구현 과정

보고싶어요 페이지에 토큰과 데이터 받아오기

보고싶어요 페이지 구현 과정


📍 Errors & Blockers

🚫"Warning: Each child in a list should have a unique "key" prop."

해당 에러는 map 함수를 작성할 때마다 나타났다. 화면에 나타나는 UI에는 문제가 없었지만 에러 문구가 console에 표시된다. 렌더링이 잘 된다고 해서 에러를 무시할 수는 없었다.

👌해결 과정
React 공식문서에서 배열 데이터에 map함수를 사용할 때는 map함수 안의 컴포넌트(태그)에 key 속성을 부여해야 한다는 것을 알게 되었다.

  • 리액트 공식문서
    Key는 React가 어떤 항목을 변경, 추가 또는 삭제할지 식별하는 것을 돕습니다. key는 엘리먼트에 안정적인 고유성을 부여하기 위해 배열 내부의 엘리먼트에 지정해야 합니다.

여기서keyprops로 넘겨줄 수 없으며 존재만으로 역할을 한다.
또한 index값보다는 id 값을 key로 부여하는 것을 지향한다.
왜냐하면 index값은 배열의 요소 수정으로 변할 수 있기 때문이다.

💻적용한 코드

//MainBox.js
<ul className="filmList">
  {movies.map(movie => (
   <Film slide={slidePx} key={movie.id} movie={movie} />
   ))}
</ul>

//WishList.js
{wish.map(wishEl => (
  <li className="wishFilm" id={wishEl.id} key={wishEl.id}>이하생략</li>

🚫"Cannot read properties of undefined"

해당 에러는 map함수를 사용할 때는 나타나지 않았지만 넘겨받는 props를 따로 사용할 때마다 마주했다. 그리고 렌더링이 되지 않았으며 화면에 바로 ERROR 창을 띄었다.
문제는 나뿐만 아니라 다른 팀도 같은 에러를 만났다. 같이 해결하기 위해 구글링했다. 하지만 "Cannot read properties of undefined"라는 에러는 다양한 경우에 나타났다. 그래도 다행히 다른 팀원과 나는 같은 원인에서 비롯된 같은 에러였다.

👌해결 과정
undefined의 속성을 찾을 수 없다는 것은 넘겨준 데이터가 undefined라는 뜻이다.
분명 서버에서 fetch 함수로 데이터를 받아 movies라는 변수에 담아 자식 컴포넌트에 넘겨주었다. 그 결과가 map 함수를 통해서 잘 나타났다.
따라서 console.log(movies)를 여러 곳에 작성하여 데이터가 잘 받아와지는지부터 확인했다.
콘솔에는 첫 번째 렌더링 시 빈 배열이 찍혔고, 두 번째 렌더링시 넘겨준 배열에 담긴 데이터가 찍혔다.
💡Ah ha Moment!
처음 데이터를 받아 변수에 담을 때 useState를 사용했다. 그리고 초깃값을 빈 배열로 할당했다.

const [movie, setMovie] = useState([]);

그러니 처음 렌더링 시 빈 배열이 출력되고 useEffect를 통해 다시 렌더링 될 때 데이터가 담긴 배열이 출력되는 것이다.

따라서 첫 렌더링 때 movies.namemoviesundefined이기 때문에 undefined인데 무슨 속성을 나타내라는 것이냐며 에러를 반환하는 것이었다.

이를 방지하기 위해서 조건부 렌더링을 사용했다.

💻 적용한 코드

<p className="filmTheme">{movies.length && movies[1].name}</p>

//아래의 코드도 가능하지만 위의 코드를 지향한다.
<p className="filmTheme">{movies[1]?.name}</p>

빈 배열을 자바스크립트 형태로 나타내려면 배열의 길이를 사용한다.
조건부 렌더링은 조건이 true라면 && 다음 문장을 실행하고 false라면 아무것도 하지 않는다.
movies.length가 0이라면 falsy한 값이기 때문에 아무런 동작을 하지 않고,
movies.length가 1 이상이라면 truthy한 값이기 때문에 movies.name을 반환한다.

추후 개발 과정에서 해당 코드를 반복해서 작성해 다른 방법을 찾다가 아예 return문 이전에 빈 배열이면 함수를 종료시키는 if문을 통해서 배열에 데이터가 담겨 있을 때만 return문 안에서 작동할 수 있도록 설정했다.

import React, { useEffect, useState } from "react";
import MainBox from "./components/MainBox/MainBox";
import "./Main.scss";

const Main = () => {
  const [movies, setMovies] = useState([]);

  useEffect(() => {
    fetch("http://10.58.2.194:8000/films?genre=드라마&sort=random&limit=20")
      .then(res => res.json())
      .then(data => {
        setMovies(data);
      });
  }, []);

  if (movies.length === 0) return;

  return (
    <div className="mainWrapper">
      <MainBox movies={movies.results} />
    </div>
  );
};

export default Main;

🚫영화 목록이 없을 때 슬라이드 버튼 보이지 않게 하기

해당 문제는 Blocker였다.
더 이상 보여줄 영화 목록이 없다면 ▶️ 모양의 버튼이 클릭 되는 동시에 사라져야 한다.
하지만 반복해서 한 번 더 클릭해야 버튼이 사라진다.

👌해결 과정
이럴 때는 구글링보다는 내가 작성한 코드를 꼼꼼히 살피며 이해하고 한 단계씩 글로 로직을 써본다.
1. 초기 화면에는 ◀️ 버튼은 보이지 않는다.
2. ▶️ 버튼이 한 번 클릭되면 즉, x축으로 -1375px 움직이면 ◀️ 버튼이 나타난다.
3. ▶️ 버튼을 누르면 -1375px 씩 이동한다.
4. 영화 목록이 없다면 ▶️ 버튼이 사라진다.
5. 각 버튼이 나타나지 않을 때는 비활성화 되어야 한다.

하나씩 해결해 나가다 보면 어느새 로직이 레고처럼 맞춰져 성공적인 결과물을 만들어낸다. 뿌듯함은 배가 된다.


⛳ 프로젝트를 마무리하며

📍 힘들었던 점
📍 스스로를 칭찬하고 싶었던 점
📍 프로젝트 전 / 후의 나


📍 힘들었던 점

🧩나의 코드, 너의 코드는 없다. 결국은 다 같이 만들어 나가는 것.
프로젝트 초반에는 서로가 담당한 페이지를 구현하거나 데이터 테이블을 만드느라 정신이 없었다.
동료가 어떤 코드를 작성하던 나의 코드를 작성하느라 신경을 쓰지 못했다.
하지만 각각의 코드는 모두 연결되어야 하며 만약 이를 알고 시작했더라면 시간을 좀 더 아낄 수 있지 않았을까 아쉬움이 든다.
2주차쯤 조금의 여유가 생기며 프런트, 백 할 것 없이 서로의 코드를 같이 고민하고 해결했다.
오히려 더 효율적으로 프로젝트를 진행하게 되었다. 혼자서 끙끙 나만의 코드를 작성하지 말고 모르거나 고민이 있으면 팀원과 그 짐을 나누자. 훨씬 가볍게, 빨리 정상에 도착할 수 있다.

🧩백엔드? 프런트 공부할 것도 많은데 굳이 알필요 있나?
무조건 알아야 한다. 결국은 프런트와 백은 한 몸이다. 둘 중 하나라도 없다면 서비스 구현은 할 수 없다.
정확한 Python, Django 가 어떻게 작동되는지는 몰라도 데이터의 형태, 구조, API 등 기본적인 백엔드 지식이 있어야 한다.
백엔드도 마찬가지로 프런트에게 넘겨줄 데이터가 어떤 형태인지 숙지한 상태로 데이터를 구성해야 한다.

벡엔드 분들이 데이터 테이블을 만들 때 프런트에게
"어때요? 괜찮아요?"라며 우리의 의견을 물어봤다.
괜찮다고 했다. 무엇인지도 모르면서 그냥 "네! 뭐 괜찮은 거 같은데요?"
통신하기 시작하며 그 무책임했던 말이 그대로 날아와 프로젝트에 난항을 안겨주었다.
팀원들끼리 항상 하는 말,
"처음에 데이터 테이블 짤 때 무조건 같이 짜야 했어요. 프런트와 백이 같이 구현해야 추후 시간도 절약하고 머리도 덜 복잡해져요."
언제나 소통이 우선이다. 협업은 코드보다는 소통이다.


📍 스스로를 칭찬하고 싶었던 점

👍 1일 1PR
프로젝트 시작 전, 멘토님께서
"하루에 PR 1개 작성할 수 있도록 노력하세요."라고 하셨다.
GitHub에 Pull Request를 남기는 것은 많은 시간이 필요했고 솔직히 귀찮은 일이다.
하지만 한 번 해보기로 했다. 매일 출퇴근 지하철 안에서 PR을 작성했다. 오늘은 어떤 기능을 구현했으며, 어떤 부분이 어려웠는지, 그로 인해 내가 무엇을 배웠고 어떻게 성장했는지, 수정사항은 무엇인지, 어떤 부분을 리팩토링 했는지 등 개발 일기를 써 내려 갔다.
처음에는 귀찮았던 PR 작성이 이제는 기록하지 않으면 찝찝한 기분이 들 정도로 습관이 되었다.
프로젝트가 끝날 무렵 멘토님께서 "PR을 정말 잘 작성해주셨어요. 이러면 기업에서 이력서 및 면접 시 수강생에게 큰 도움이 될 거예요!"라고 해주셨다.

수많은 자기개발서의 공통 조언은 "메모해라", "기록해라"이다.
퇴근길 지하철에서 한 줄 한 줄 써 내려간 글이 추후 큰 자산이 될 수 있다.

👍 솔직한 피드백, 긍정적인 에너지
프로젝트 중간 발표가 있었다. 매일 아침 stand up meeting을 했지만 팀원들과 활발한 소통을 하고 있다는 생각이 들지 않았다.
그래서 솔직하게 모두 모인 자리에서 우린 소통이 부족하다, 프런트와 백뿐만 아니라 같은 프런트까지 서로가 어떤 일을 하고 있는지 충분히 공유되지 않고 있다고 얘기했다. 모두 조금은 동의하는 눈치였다. 그 후 우리는 눈에 띄게 달라졌다. 거의 열띤 토론을 하며 서로의 업무를 공유했다. 결과적으로 서로의 분야에 대해 더 잘 알게 되었고 프로젝트 진행도 효율적인 방향으로 나아갔다.

나는 활력이 넘치는 편이다. 위코드에서 12시간 이상을 보내면서 최대한 모든 에너지를 방출한다. 2주 동안 "할 수 있다!!!"를 입에 달고 살았다. 내 옆에 있는 사람들과 긍정적인 기운을 나누고 싶었기 때문이다. 어차피 해야 할 프로젝트 즐기면서 하면 제일 좋지 않을까!


📍 프로젝트 전 / 후의 나
프로젝트 전, 나는 컴포넌트를 만들 줄 몰랐다. 리액트를 키는 순간부터 수업 영상을 같이 켰다. 자신감도 없었다.
팀원들에게 피해를 주기 싫어 혼자 끙끙 앓고 긴장도 많이 했다.

지금은 백엔드 지식까지 습득하며 팀원들의 코드를 함께 모니터링 하는 개발자가 되었다. 직접 부딪히며 코드를 작성하는 내 모습이 기특하다고 느껴질 정도다.
코딩 실력뿐만 아니라 소통하는 법을 배웠다. 프로젝트에 막히는 부분이 있다면 여러 가지 솔루션을 제시하기 보다는 명확한 해결책과 설득력 있는 근거를 제시했다.

Watcha Classic 프로젝트는 나에게는 축구 경기와도 같았다. 팀 안에서 한 명의 선수가 되어 최선을 다해 달리지만 옆에 있는 동료 선수도 챙기며 최상의 경기를 끌어내 가는 모습. 결국 팀프로젝트는 내가 아닌 우리라서 가능했다.

profile
Front-end Developer

0개의 댓글