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

김형빈·2024년 6월 7일
0

내일배움캠프

목록 보기
36/81

오늘의 한 일

  • 발라드 커뮤니티 (팀 프로젝트)
    • 게시글 추천 기능
    • 수정 페이지 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.

0개의 댓글