[TIL] 내일배움캠프 React 과정 2024.06.07

김형빈·2024년 6월 7일
0

내일배움캠프

목록 보기
36/81
post-custom-banner

오늘의 한 일

  • 발라드 커뮤니티 (팀 프로젝트)
    • 게시글 추천 기능
    • 수정 페이지 css
    • 기능 구현 완료
    • 발표
  • 팀 프로젝트 정보

오늘의 문제

게시글 추천 기능

  • 어제 진행했던 댓글은 데이터베이스 구현 문제 때문에 시관 관계상 후순위로 미루고 게시글의 추천 기능을 구현하기로 했다.
  • 어제 튜터님께 들었던 조언을 토대로 추천을 눌렀는지 여부와 추천 숫자를 state로 변경시키고 특정 시점에 supabase(백엔드)에 데이터를 업로드하는 로직을 구현하기로 했다.
  • 문제는 특정 시점인데 팀원 분인 unmount 될 때 데이터를 업로드하는 아이디어를 주셨다.
  useEffect(() => {
    const increasedViews = post.views + 1;
    const increasePostView = async (increasedViews, postId) => {
      await updatePostViews(increasedViews, postId);
    };
    const increaseLikeNum = async (postId, userId) => {

      await insertLikeUser(postId, userId);
    };

    const decreaseLikeNum = async (postId, userId) => {
      await delLikeUser(postId, userId);
    };
    return () => {
      increasePostView(increasedViews, postId);
      if (user && !isDataHasUser && isLike) increaseLikeNum(postId, userId);
      if (user && isDataHasUser && !isLike) decreaseLikeNum(postId, userId);
    };
    //eslint-disable-next-line
  }, []);

  const handleLikeClick = () => {
    if (user) {
      if(isLike){
        setIsLike(false);
        setLikeNum((prevNum) =>prevNum - 1);
      }
      else {
        setIsLike(true);
        setLikeNum((prevNum) => prevNum + 1);
      }
    } else {
      navigate('/login');
    }
  };

아이디어로 제작한 코드

  • 클라이언트의 state는 handleClick에서 관리한다.
  • 컴포넌트가 unMount 될 때 state를 바탕으로 데이터를 업로드 한다.
  • 컴포넌트가 unMoute 될 때 함수를 실행시키기 위해 useEffect를 사용하였다.

첫 번째 문제 발생 및 해결 방법

  • 그러나 문제가 있었으니 useEffect에서 컴포넌트가 Mount 될 때의 state 정보를 보관하고 있었다.

  • 그렇다면 useEffect에 state 정보를 전해주면 되는거 아닌가?

  useEffect(() => {
    const increasedViews = post.views + 1;
    const increasePostView = async (increasedViews, postId) => {
      await updatePostViews(increasedViews, postId);
    };
    const increaseLikeNum = async (postId, userId) => {

      await insertLikeUser(postId, userId);
    };

    const decreaseLikeNum = async (postId, userId) => {
      await delLikeUser(postId, userId);
    };
    return () => {
      increasePostView(increasedViews, postId);
      if (user && !isDataHasUser && isLike) increaseLikeNum(postId, userId);
      if (user && isDataHasUser && !isLike) decreaseLikeNum(postId, userId);
    };
    //eslint-disable-next-line
  }, [isLike]);

의존성 배열에 isLike라는 state를 넣은 코드

  • 이제 useEffect에서도 state 정보가 제대로 전달되었고, 동작도 잘 된다.
  • 그럼 이제 진짜로 문제가 해결된 걸까??

두 번째 문제 발생

  • 그러나 위의 코드에도 문제가 있다
  • 좋아요 버튼을 누를 때마다 백엔드와 통신하지 않게 하려는 의도에서 벗어나는 것!
    • 그러나 위의 코드에서는 isLike가 바뀔 때마다 컴포넌트가 Update 되고, 결과적으로 useEffect가 실행 되므로 결과적으로는 버튼을 누를 때마다 백엔드와 통신하게 된다...
  • 추가적으로 창을 닫으면 컴포넌트가 unMount 되지 않는다...
    • 사용자가 좋아요 버튼을 누르고 다른 페이지로 이동하지 않은 채 창을 닫는다면 사용자가 의도하지 않은 결과가 화면에 반영된다.

최종 좋아요 버튼 구현 방법

  const handleLikeClick = () => {
    if (user) {
      if (isLike) {
        setIsLike(false);
        setLikeNum((prevNum) => prevNum - 1);
        delLikeUser(postId, userId);
      } else {
        setIsLike(true);
        setLikeNum((prevNum) => prevNum + 1);
        insertLikeUser(postId, userId);
      }
    } else {
      navigate('/login');
    }
  };
  • useEffect를 통해서 좋아요 버튼 기능을 최적화하려던 방식을 포기하고 handleLikeClick 함수를 구현하였다.
  • 튜터님께서 조언해주시길 최적화하려는 시도는 좋았으나, 특히 통신 환경이 좋아진 요즘에는 크게 속도 차이가 없다면 성능 최적화를 위해 통신 횟수를 줄이는 거 보다 오히려 매번 데이터 통신을 하여 데이터를 정확하게 가지고 있는 것이 더 좋은 방법일 수 있다고 조언해주셨다.

다른 분들은 좋아요 기능을 어떻게 구현하였을까?

  • 다른 방법으로는 useCallback을 사용하는 방법을 보긴 하였으나 내 의도와 맞는 방법인지는 아직 판단이 서지 않는다.

오늘의 회고

드디어 길다면 길고 짧다면 짧은 프로젝트가 끝났다. 이번 프로젝트는 결과물을 완성해낸 것만으로도 대단하다고 느껴질 만큼 시간과의 싸움이었다. 특히 supabase를 공부하면서 진행하느라 안 그래도 부족했던 시간에 쫓기면서 작업을 진행하였다. 스파르타 캠프를 진행하면서 이렇게 촉박했던 적은 처음이었다... 그래서 끝나니까 더욱 아쉬움이 남는 프로젝트였다. 팀원들과도 잘 맞는 부분도 있었지만 잘 안 맞았던 부분들이 있었어서 소통의 중요함, 처음 기획의 중요함도 다시 배워가는 프로젝트이다... 그래도 나름 팀원들 중 잘하는 위치에 있기에 부담감이 있었는데 이겨내서 그나마 얻어가는게 있다고 생각이든다. 그래도 앞으로의 프로젝트가 계속 이렇게 진행된다면 앞으로의 대비가 필요할 듯하다...
profile
The secret of getting ahead is getting started.
post-custom-banner

0개의 댓글