73일차 TIL: 리액트 네이티브 프로젝트 - 좋아요 기능

변시윤·2023년 1월 12일
0

내일배움캠프 4기

목록 보기
78/131
post-custom-banner

좋아요를 안 한 상태라면 좋아요, 좋아요를 한 상태라면 좋아요 취소 구현하기

useState로 관리하기(실패)

  const [likes, setLikes] = useState(item.likes);
  const [liked, setLiked] = useState(item.liked);

  const changeLikes = () => {
    if (!item.liked) {
      setLikes((prev) => prev + 1);
      setLiked(true);
    }
    if (item.liked && item.likes > 0) {
      setLikes((prev) => prev - 1);
      setLiked(false);
    }
  };
  
    const onChangeLikes = async () => {
    try {
      changeLikes();
      await calculate({ id: item.id, likes, liked });
    } catch (error) {
      console.log("error", error);
    }
  };
  1. DB에 likes(좋아요수), liked(좋아요 여부) 추가
  2. useStatelikes, liked 관리
  3. 하트를 클릭할 때마다 setLikes, setLiked 실행
    • likedfalse라면 setLikes((prev) => prev + 1)
    • likedtrue라면 setLikes((prev) => prev - 1);

버그
좋아요가 1씩 증가하거나 감소하지 않고 2씩 동작

onChageLikes가 실행되면 setLikes는 매번 실행되지만 setLiked는 두 번째에만 실행이 되기 때문인데, 서버와 통신하게 되면서 setState의 순서를 보장하지 못하게 되었기에 해당 버그가 발생했다.

튜터님께 조언을 구해보니 이 부분은 내가 코드를 잘못 짠 게 아니고 원래 useState라는 놈이 그렇다고 한다.. 그래서 프로젝트의 규모가 커질수록 useState로 관리하는 일이 잘 없다고 한다.



배열로 관리하기(성공)

  const likesArray = item.userLikes;

  const countLikes = () => {
    if (!likesArray.includes(item.userId)) {
      likesArray.push(item.userId);
    } else if (likesArray.includes(item.userId)) {
      const idx = likesArray.indexOf(item.userId);
      likesArray.splice(idx, 1);
    }
  };
  1. DB에 userLikes 배열 생성
  2. 좋아요 실행시 userLikes에 현재 userId 추가
  3. 좋아요 취소시 userLikes에서 해당 userId와 일치하는 값 제거
  4. 좋아요수는 userLikes 길이로 반환

이런 로직으로 구현하니까 버그도 없고 코드도 훨씬 깔끔해졌다! 물론 이것도 배열에서 특정 요소 제거하는 부분에서 또 한참 헤맸다 ㅎ... 알고리즘 한창 풀었을 땐 비슷한 문제 뚝딱 풀었었는데 한동안 안하다 보니 또 기억이 나질 않는다.... 자바스크립트의 중요성을 또 한 번 느꼈다.


어제 하루종일 붙들고 있느라 스트레스 이빠이 받았지만 그래도 공부가 정말 많이 되어서 결과적으로 아주 만족스럽다.
profile
개그우먼(개발을 그은성으로 하는 우먼)
post-custom-banner

0개의 댓글