11.7 Favorite Products part two

with-key·2022년 3월 20일
0

좋아요 기능 구현하기 2

1. optimistic UI 구현

정의
optimistic UI란, 서버의 응답 없이 UI가 변경되는 것을 의미한다. 즉 유저가 좋아요 버튼을 눌렀을 때, 서버로부터 toggle에 대한 결과값을 응답 받기전에 유저의 의도대로 UI를 변경한다. 클라이언트의 요청이 높은 확률로 성공할 것임을 예측하고 유저의 액션을 수행한다. 장점으로는 유저 입장에서는 아주 빠른 응답성을 보여주고, 단점으로는 자칫 클라이언트의 요청이 실패했을 때 유저의 의도와 전혀 다르게 화면이 보여질 수 있다. 그래서 optimistic UI를 구현하고자 한다면, req 실패에 대한 대응도 세워야 한다.

//post 요청이므로, useMutation()
const [toggleFav, { data, error, loading }] = useMutation(`/api/products/${router.query.id}/fav`);

const onFavClick = () => {
  toggleFav({});
}

return (
  //...
  
  <button onClick={onFavClick}>  {/* 좋아요 버튼 */}
)

현재 유저가 해당 게시물에 대하여 '좋아요'를 했는지 확인하기
Fav Record는 Product, User 정보를 모두 가지고 있다. 이것을 활용해서 현재 유저의 정보와 유저가 머무르고 있는 Product의 값을 모두 가지고 있는 Fav Record를 찾아낸다. 만약 두 조건을 모두 충족하는 Fav Record가 있다면, 해당 Product에 대해 User가 'Like'를 한 것이고, Record가 없다면 'Unlike' 한 것이다. db에서는 record가 없다면 null을 return 하고 있다면, { } 를 return 한다.

// record를 조회하고, 그 여부를 boolean으로 변환해서, response에 담는다.
const isLiked = Boolean(
  await client.fav.findFirst({
  where: {
    userId: user?.id, // req.session에서 가져옴
    productId: product?.id, // req.query에서 가져옴 
  }, 
  select: {
    id: true, // fav record의 모든 정보를 거져올 필요는 없으므로.
  }
  })
);
  
res.json({
  ok: true, product, isLiked, relatedProducts  
})

프론트 작업
client에서는 fetching 한 data에서 isLike가 true, false일 때 각각 스타일을 넣어준다.

const { data } = useSWR<ProductDetailResponse>(
    router.query.id ? `/api/products/${router.query.id}` : null
  );

// data === {ok: true, product: {…}, isLiked: true, relatedProducts: Array(0)}
profile
주니어 프론트엔드 개발자 입니다.

0개의 댓글