[프로젝트] 메인 프로젝트 : 2주차 일지

Jade·2023년 1월 14일
2

프로젝트

목록 보기
12/28
post-thumbnail

🟡 Main-Project Goals

  • 기획부터 디자인, 개발, 배포까지 ! = 우리 팀만의 어플리케이션 개발
    우리 '쓰앵님'조가 만들기로 한 어플리케이션 이름은 '과외차이'
  • 팀장 직책을 자원해서 맡은 만큼 항상 팀원들보다 '조금 더!' 하기
  • 기능 구현 내에서 도전 과제 설정 및 수행
  • 단순한 기능 구현을 넘어 클린 코드 작성, 효율적 코드 작성에 신경쓰기
  • as always 소통에 힘쓰자
  • 매주 일지 남기기


🟡 Process

  • 백엔드 팀의 폭주... 슬쩍 물어만 봐도 아래 짤과 같이 해내버리는 그들...
    덕분에 프론트 팀은 프론트 팀 업무에만 집중할 수가 있었다.

  • 고레벨 프로토타입 완성

  • 고레벨 프로토타입을 기반으로 페이지 마크업 작업
    : 마크업 작업이라고는 하지만, 작업 후에 바로 서버와 데이터 통신에 들어가야 하기 때문에 기능 구현을 위한 준비도 마쳐두게 되었다.

  • 데이터 통신 전에 작성한 코드들 리팩토링
    : 모달 컴포넌트를 사용하는 데 있어 props-drilling이 심했고, 유지 보수에 어려움이 있을 것으로 예상되어 recoil을 이용한 리팩토링을 진행했다. (덕분에 팀원들 모두 주말에 잘 쉬지 못했다... )

  • 다음주부터는 데이터 통신에 들어갈 수 있을듯!



🌕 Hard Points & Solutions

😱 PostCSS 친 해 지 길 바 라 ~~~

PostCSS를 처음 사용하다 보니 우여곡절이 좀 있었는데, 우선 Extension은 'PostCSS Language Support'가 아닌 'PostCSS Intellisense and Highlighting'를 사용하기로 했다.
다운로드 수가 많고 가장 위에 떠서 전자를 선택했었는데, 자동완성이 안 되니 너무 불편했고, 팀원 중 한 명이 후자를 추천해주어서 사용해보니...훨씬 편했다.

PostCSS에 대한 이해가 부족해서 생겼던 다른 일 중 하나는 마크업을 어느정도 마무리하고 팀원들과 휴식 시간을 가지려고 했을 때 일어났다... 쉬면서 만들어둔 웹 페이지나 감상하자며 npm run start를 터미널에 입력하고 난 뒤 본 화면은...

css 파일을 모듈화해서 사용하더라도 그 모듈 안에서 전역으로 (ex: 클래스네임이 아닌 전역 input에 대한 css 지정 시 등) css를 작성하면 모듈을 벗어나 같은 파일 내 즉, 말 그대로 전역에 영향을 미치게 된다...

그 점을 모르고 코드를 작성한 탓에 발생한 에러였다.
마크업 단계에서 알아챘으니 다행이라고 생각한다...



😵‍💫 눈을 떠보니 그곳은... 모달 지옥이었습니다.

메인 프로젝트 초반부부터 기술 스택을 정하면서 상태 관리 라이브러리로 뭘 사용할지에 대해 이야기를 많이 나눴는데, 그렇게 추려진 후보가 recoil,jotai,zustand 정도였다.

결과적으로 recoil을 선택한 건 리액트에 친화적이라는 것이 가장 큰 이유였고,
여태 redux를 사용했을 때 flux 패턴을 따랐던 것과는 다르게 atom 방식을 사용한다는 것도 흥미로웠기 때문에 새로운 도전을 해보자는 것도 있었다.

마크업 단계에서 단순히 모달을 컴포넌트로 관리하면 별 문제 없겠거니...했지만
모달을 관리하기 위해서는 각 모달마다 상태가 있어야 했고, 한 페이지에서 띄워야 하는 모달이 늘어나면 늘어날 수록 상태도 하나둘 늘어났다.


모달 다음에 모달 다음에 모달...

이게 맞나...?

싶었던 나와 팀원들은 직감으로 이제 recoil을 사용할 때가 왔다는 것을 알았고, 피같은 주말에도 공부를 하기 위해 구글 검색을 하기 시작했는데...

구글 검색을 해보니 recoil로 modal 상태 관리를 구현한 예시글은 대부분 TypeScrip를 이용한 것이었다.

Ts가 중요한 언어라는 점은 잘 알지만 메인 프로젝트 기간 동안 Ts를 배워서 적용하기에는 부담이 크다고 생각했기 때문에 팀원들과는 익숙한 React를 사용하기로 합의한 상태였다.

Ts 문법을 잘 모르는 상태에서 Ts로 Recoil을 사용해 modal 관리를 하는 글들을 보는 것은 꽤 고통스러웠고... 그래서 보고 따라하기 보다는 Recoil 예제를 이용해 간단한 것부터 만들어보기로 했다.

recoil의 Atom은 useState 상태와 굉장히 유사한 형태로 사용할 수 있었고, selector는 공부하면서 이해하기로는 해당 상태 값을 변형시키지 않고 그 값을 가공할 수 있도록 도와주는 함수라고 이해했다. side-effect를 방지하기 위한 순수 함수라고 하는데, 사실 이 selector에 대한 개념은 조금 더 직접 부딪혀 보기 전까지는 크게 와닿지 않을 것 같다는 느낌도 들었다.

atom, selector 외에도 atomFamily, selectorFamily 와 같은 도구들도 있는 것 같았지만, 팀원들과 함께 공부해보며 얻은 결론은 모달 관리를 위해서는 atom 외에 다른 도구들을 사용하지 않아도 될 것 같다는 것이었다.

아래는 걸출한 팀원 한 분이 redux 모달 관리 게시글들을 보면서 confirm, alert 모달을 작성한 것에 숟가락을 얹어서 프로젝트에 사용되는 네 가지 모달을 모두 완성시켜 본 코드이다.

위 코드들을 기반으로 주말동안 모달 관리 리팩토링을 진행했다.



⭐️ 별점과 씨름하기...

과외 매칭 기능이 주요 기능 중 하나이다보니 튜터의 별점을 매기고, 해당 별점을 기반으로 평점을 산출해서 보여주는 기능도 필요했다.

별점을 입력하는 기능은 구글링을 통해 어렵지 않게 구현했지만, 별점을 실제로 보여줄 때에는 어려웠던 점이 평점이 서버에서 정수로 날아오는 게 아니라 0.5 단위의 실수로 날아온다는 점이었다.

처음에는 아래와 같이 makeStars라는 함수를 만들어서 stars라는 배열을 구하고, 해당 배열을 map으로 돌리는 방식으로 구현했다.


//yellow, gray, half는 각각 꽉 채워진 별, 빈 별, 반쪽짜리 별 
const makeStars = (yellow, gray, half = 0) => {
    const arr = [];
    for (let i = 1; i <= yellow; i++) {
      arr.push('y');
    }
    if (half !== 0) {
      arr.push('h');
    }
    for (let i = 1; i <= gray; i++) {
      arr.push('g');
    }
    return arr;
  };

//rate가 받아온 평점
 const stars = Number.isInteger(Number(rate))
    ? makeStars(rate, 5 - rate)
    : makeStars(Math.floor(rate), 5 - (Math.floor(rate) + 1), 1);


//아래와 같이 컴포넌트 return문 내부에서 map을 돌려줌 
 <div className={styles.stars}>
          {stars.map((el, index) => {
            if (el === 'y') {
              return <MdStar key={index} className={styles.yellowStar} />;
            } else if (el === 'g') {
              return <MdStarOutline key={index} className={styles.emptyStar} />;
            } else {
              return <MdStarHalf key={index} className={styles.halfStar} />;
            }
          })}
        </div>

척 봐도 알 수 있다시피... 굉장히 복잡한 방식으로 구현했기 때문에 멘토링을 받을 때 멘토님께서 깜짝 놀라셨던...

멘토님 조언을 받아 아래와 같이 구현하기로 했다.

switch case 문과 new Array를 적절하게 사용하면 조금 더 쉽게 구현이 가능했다.
사실 new Array와 fill까지는 어떻게 생각해봤었는데, 당시에 피그마 만지기만 쭉 하다가 오랜만에 코드 작성을 했고, 알고리즘 문제를 푼 지도 꽤 되고 하다보니... 좀처럼 쉽게 로직이 안 떠올랐다.

프로그래머스 꾸준히 풀어야지...

  <div className={styles.stars}>
            {new Array(5).fill('star').map((_, count) => {
              const star = Number(rate);
              const checkedStar = (star) => {
                if (count + 1 - 0.5 === star) return 'half';
                else if (count + 1 > star) return 'dimmed';
                else return 'colored';
              };

              const renderStar = (color) => {
                switch (color) {
                  case 'dimmed':
                    return (
                      <MdStarOutline key={count} className={styles.emptyStar} />
                    );
                  case 'half':
                    return (
                      <MdStarHalf key={count} className={styles.halfStar} />
                    );
                  default:
                    return <MdStar key={count} className={styles.yellowStar} />;
                }
              };
              return renderStar(checkedStar(star));
            })}
          </div>


🟡 Needs

  • recoil 공부 + 블로깅
  • 컨디션 관리 (억지로라도 쉬는 시간 만들어야 함)
profile
키보드로 그려내는 일

4개의 댓글

comment-user-thumbnail
2023년 1월 16일

리코일 좋아,,

1개의 답글
comment-user-thumbnail
2023년 1월 16일

네 됩니다 다음분~

1개의 답글