[TIL] 240727 (최종 프로젝트 자취템 리스트 더보기 적용, 공구 신청자 입금 여부 변경 기능 완료)

·2024년 7월 27일

TIL

목록 보기
111/268
post-thumbnail

🥞 오늘 한 일

  • 최종 프로젝트
    • 마이 페이지 내가 쓴 공구
      • 입금 여부 체크 기능 완료
      • optimistic update 자체 구현
      • 게시물 리스트 최신 순으로 정렬
      • 각 게시물 별 공구 신청자 created_at 기준으로 정렬
      • 타입 지정
    • 공구 신청 모달
      • 전화번호 유효성 검사 추가 (정규 표현식 사용)
    • 자취템 리스트
      • 더보기 기능 완료
      • 검색 기능에서 쓰이던 함수 변경으로 인해 새 함수 및 route handler 제작

🍽️ 트러블 슈팅

입금 여부 체크 시 optimistic update로 제작

인풋 체크박스로 제작하지는 않았지만, 체크박스인 것처럼 보이게 하고 싶어 optimistic update를 적용하고 싶었다.
optimistic update에 관해서 tanstack query에서 적용하는 방법을 일전에 배운 적이 있지만 상당히 복잡해서, 기존에도 쓰던 방식을 적용시켜보았다. 코드는 아래와 같다.

function MyGroupApply({
  groupApply,
  idx,
  refetch,
}: {
  groupApply: GroupApplication;
  idx: number;
  refetch: () => void;
}) {
  const user = useAuthStore((state) => state.user);

  useEffect(() => {
    setIsPaid(groupApply.is_paid); // groupApply.is_paid가 바뀔 때마다 정확한 값을 isPaid에 적용
  }, [groupApply.is_paid]);

  const queryClient = useQueryClient();

  const [isPaid, setIsPaid] = useState(groupApply.is_paid);

  const updateMutation = useMutation({
    mutationFn: async (newGroupApply: GroupApplication) => {
      await editMyGroupApply(groupApply.id, newGroupApply);
    },
    onSuccess: async () => {
      await queryClient.invalidateQueries({
        queryKey: ["myGroupPosts", user?.id],
      });
      await refetch();
    },
  });

  const paidGroupApplyHandler = async () => {
    const newGroupApply: GroupApplication = {
      ...groupApply,
      is_paid: !isPaid,
    };
    setIsPaid(!isPaid); // 여기서 미리 적용해준다.
    updateMutation.mutate(newGroupApply);
  };

  return (
    <>
      <td className="p-2">{idx + 1}</td>
      <td className="p-2">{groupApply.user_name}</td>
      <td className="p-2">{groupApply.user_phone}</td>
      <td className="p-2">
        {groupApply.user_address} {groupApply.user_detail_address}
      </td>
      <td className="p-2 text-center">
        <div onClick={paidGroupApplyHandler} className="w-6 h-6 cursor-pointer">
          {isPaid ? (
            <div className="bg-red-1 w-full h-full"></div>
          ) : (
            <div className="bg-black w-full h-full"></div>
          )}
        </div>
      </td>
    </>
  );
}

isPaid 부분에 주목을 하며 보면, 받아온 groupApply.is_paid를 isPaid에 넣어주고 그 외의 로직은 전체적으로 isPaid를 사용한다. 입금 여부를 변경 시 아직 데이터베이스에 적용은 되지 않았지만 미리 setIsPaid를 통해 내부 값을 변경해주고 이 경우 바로 화면에 적용된다. 그리고 서버에 바뀐 값을 보내고 받아온 다음, groupApply.is_paid가 변경되었을 경우 해당 값을 setIsPaid로 적용시킨다. 이렇게 되면 내가 임의로 (낙관적 업데이트로) 지정한 부분은 자연스레 정확한 값으로 바뀌게 된다. 나는 이런 식으로 optimistic update를 간단하게 구현했다.

🍴 돌아보기

주말 간에 해야할 목표는 일단 1차적으로 무사히 끝났기에 다행이다. 내일은 임의로 만들어둔 와이어프레임을 토대로 결제 페이지들을 제작해보아야겠다.

🍳 내일 목표

  • 최종 프로젝트
    • 결제 관련 페이지들 폴더 구조 작성, 마크업 및 기능 구현 (가능한 부분까지)
profile
웹 프론트엔드 개발자

0개의 댓글