Winnerest Project 회고록

Pulan·2022년 9월 10일
0

위코드에서의 마지막 프로젝트에서 겪었던 느낌을 다시 한 번 생각해보았다.

프로젝트 소개

  • 사용자의 이미지를 스크랩하고 포스팅하여 다른 사용자와 공유하는 SNS(소셜 네트워크 서비시)인 핀터레스트 사이트를 모티브로 프로젝트를 진행하였다.

개발 기간

  • 2022년 8월 29일 ~ 2022년 9월 8일 (10일)

인원

  • 프론트엔드 개발자 : 김다현, 조은지, 권영준
  • 백엔드 개발자 : 백민석, 길성민

기술 스택

FRONT-END

  • React / React Router / styled-components / Axios

BACK-END

  • Node.js, Mysql, Express.js, Typeorm,Postman, Jest, AWS S3

공통

  • Git, Git-Hube, Trello, Google SpreadSheet Editor (API 명세서)

구현한 기능

1. 핀 상세 페이지

  • 이미지 다운로드

    • html의 a 태그에서 download 속성을 지원해주는데 재대로 사용하지를 못한 거 같다.
  • url 복사

  • 핀 수정

    • axios에서 PATCH 메서드를 이용하여 핀의 대한 정보를 수정하였다.
  • 댓글 추가 기능

    • textarea 태그에서 글을 입력할시 엄청난 양의 렌더링이 되는데 그것을 최소화 하기 위해서 useRef를 이용하여 마지막 클릭했을 때만 입력한 값을 POST메서드를 이용하여 서버에 보냈다.
    • 핀터레스트에서는 글자를 한 번만 입력해도 확인 버튼이 활성화되는데 useRef만 사용하면 글자를 입력했는지 바로 확인이 불가능하여 useState를 같이 사용하였다.
  const reviewInputChange = e => {
    handleResizeHeight('40px');
    e.target.value.length <= 1 &&
      setIsStateObj({
        ...isStateObj,
        reviewValue: textRef.current.value,
      });
  };
  • 댓글 리뷰 좋아요 기능

    • 선택한 리뷰에 해당하는 id를 가지고 POST 메서드를 이용하여 선택된 리뷰의 id를 서버에 보내는 방식으로 해결하였다.
  • 무한 스크롤

    • 보통의 스크롤 기능만 이용하면 한 번만 휠을 움직일 시 엄청난 양의 이벤트가 발생하는데 발생되는 이벤트들을 제어하기 위해서 debounce, throttle 중 debounce 방법을 이용하여 이벤트를 제어하였다.
    • [JavaScript] 디바운스와 쓰로틀의 차이
  • 팔로우 기능

    • 좋아요 기능과 비슷한 양식으로 해결하였다.
    • 토큰을 서버단에 보내서 계산된 값을 다시 받아온 뒤 팔로우가 된 경우와 안된 경우를 분리하였다. (버튼 스타일 변경)

2. 공통 Nav 바

  • 기본 UI
  • 검색창 모달창

구현하면서 아쉬웠던 코드들

1. axios를 사용하는 코드가 중복된게 많아서 따로 커스텀 훅으로 빼놔서 관리해도 좋을거 같다.


2. 이 공간 안에서 data라는 변수의 데이터를 변경시키고 변경된 데이터를 pinData에 옮겨도 될거 같다.

필요없는 state 값을 이용해서 코드가 복잡해진거 같다.

PinInfoContainer 컴포넌트에 보내는 state 값이 {...pinData} 만으로도 가능할 거 같다.

const [pinData, setPinData] = useState({});
const [tagId, setTagId] = useState(0);
const [followBtn, setFollowBtn] = useState(false);
const params = useParams();
const token = localStorage.getItem('Token');
const getPinData = async () => {
    try {
      const res = await axios.get(`http:/주소/pins/${params.id}`, {
        headers: {
          Authorization: token,
        },
      });
      const { data } = res;
      if (data.tagIds.length > 1) {
        setTagId(data.tagIds.slice(0, 1).join());
      } else {
        setTagId(data.tagIds);
      }
      if (data.duplicatedResult === '1') {
        setFollowBtn(true);
      } else {
        setFollowBtn(false);
      }
      setPinData(data);
    } catch (err) {
      throw new Error(err);
    }
  };




3. 핀 수정 모달에서도 사용하므로 util 폴더를 생성한 뒤 관리를 해주면 좋을 거 같다.

(defaultHeight, ref값)

  const handleResizeHeight = defaultHeight => {
    textRef.current.style.height = defaultHeight;
    textRef.current.style.height = textRef.current.scrollHeight + 'px';
  };




4. useRef를 이용해서 한번에 데이터를 저장하고 보내는 형식으로 바꾸는게 좋을 거 같다.

state 값이 변경되면서 렌더링이 발생된다.

  const handleChangeInfo = ({ target }) => {
    handleResizeHeight('48px');
    setChangeInfo({
      ...changeInfo,
      [target.name]: target.value,
    });
  };




5. 글자를 1개만 쓰면 state에 저장되는데 그 과정에서 렌더링이 한 번더 일어나게 되므로 그냥 e.target.value의 길이가 0 보다 크면 "확인" 버튼이 활성화 되게하는게 좋아 보인다.

  const reviewInputChange = e => {
    handleResizeHeight('40px');
    e.target.value.length <= 1 &&
      setIsStateObj({
        ...isStateObj,
        reviewValue: textRef.current.value,
      });
  };




6. 이번 무한 스크롤에서 디바운스를 사용했으니 다음부터는 쓰로틀, intersection-observer를 사용해보고 이번 react 18 버전에서 나온 useDeferredValue라는 기능을 한 번 공부해봐야겠다.

  const debounce = (func, delay) => {
    let timer = null;

    return () => {
      if (timer) clearTimeout(timer);
      timer = setTimeout(func, delay);
    };
  };

플로우 차트

좋았던 점

  • 이전 프로젝트와는 달리 API 명세서를 만들게 되면서 통신을 좀 더 원활하게 진행이 되었다.
  • 중간에 플로우 차트를 만들게 되어 서로가 어떤 기능을 구현하는지 알 수 있게 되었고 어려운 기능이 있다면 같이 고민할 수 있게 되었다. 그리고 플로우 차트를 그리는 과정에서 회의때 놓쳤던 부분들을 다시한 번 정리할 수 있게되었다.

아쉬웠던 점

  • 저번 프로젝트와 같이 소통을 할 때 너무 소심하게 했던 거 같다. 특히 데이터를 요청할 때가 심하게 조심스럽게 해서 백엔드 입장에서 내가 필요한 데이터가 어떤 것을 원하는지 제대로 파악하기 어려워했던 거 같다.

  • 이번 프로젝트에서는 처음으로 Styled Component를 사용하게 되었는데, 프로젝트 초기에 style을 나누는 방법이 있다는 것을 알게 되었고 그 방법을 팀원들과 맞추기 위해서 이 방법을 사용하는건 어떤지 요청을 하는것이 어려웠던 거 같다.

  • 프로젝트에서 공통 컴포넌트로 나눈 기능 중에서 버튼과 모달창이 있었는데 이 기능을 사용하게되는 입장에서 인풋 값들은 많은데 어떤 형태로 인풋 값을 줘야되는지를 몰라서 그냥 해당 파일에서 스타일을 짜게되었다. 이 과정에서 해당 기능을 맡은 팀원에게 간단한 명세서를 만들어 달라는 요청과 질문을 더 했으면 어땠을까 하는 심정이 있었다.

  • 프로젝트를 진행하는 초기에 왜 이런 기능들이 있는지 기획자의 의도를 몰라서 페이지를 중간중간 바꾼 것들이 있었는데 프로젝트를 진행하다 보니 점점 더 사용자 입장에서 원래 페이지에 있는 기능들이 더 편하다고 느낄 수 있다고 생각이 들어서 해당 사이트의 대한 이해도가 거의 없었다는 것을 알게 되었다.

  • 중간중간 데이터 통신에 대해 살짝 바뀌게 된 경우가 있었는데 그때그때 문제를 급하게 해결하느라 코드를 정리를 하지 못하게 되어서, 내가 개발 실력과 지식이 더 좋았다면 그 상황에서 더 유연하게 대처할 수 있었을 거라는 아쉬움이 많다.

  • 이번 프로젝트는 개인적으로 너무 아쉬웠던 프로젝트였던 거 같다.

개선해야될 점

  • 소통을 하는 과정에서 팀원들에게 너무 조심스럽게 대해서 프로젝트의 결과물이 아쉽게 된거 같아 다음 프로젝트(?)에서는 조금 더 자신감을 가지고 해야되겠다.
  • 개발 실력과 지식이 너무 부족한 거 같아 나 자신을 평소보다 더 밀어 붙여야되겠다.
  • 코드를 짜기전에 코드가 앞으로 어떻게 변할지 생각해 보는 습관을 가져야될거 같다.
  • 마지막으로 내가 하게되는 서비스에 대해서 조금 더 생각해보고 어떻게하면 사용자가 더 편리하게 사용할 수 있게 될지 고민을 해야될 거 같다.
profile
현재 개발 중인 블로그로 내용들을 개선하면서 업데이트하고 있습니다. https://www.plu457.life/

0개의 댓글