inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

[인프런 워밍업 클럽 3기 풀스택 ] 3주차 발자국

hee j
0

목차


Netflix Clone Project

 

1. 다른 페이지에서 데이터를 받아 전달

[rocoil을 사용하는 방법]

 

[Supabase에서 maybeSingle()과 single()]

 

2. react-intersection-observer

npm install react-intersection-observer
import { useInView } from 'react-intersection-observer';

const [ref, inView, entry] = useInView({
  threshold: 0,
});
<div ref={ref}>    
  {inView && 'Element is in view!'}
</div>

 

** 우리가 왜 이것을 사용해야 하나?

[useInfiniteQuery]

const {
  data,
  fetchNextPage,
  hasNextPage,
  isFetchingNextPage,
  status,
} = useInfiniteQuery('todos', fetchTodos, {
  getNextPageParam: (lastPage, pages) => lastPage.nextPage,
});

3. 3주차 미션

 

[구현 이미지]

image
[supabase에 컬럼 추가]

import { updateFavorit } from "actions/movieActions";
import Link from "next/link";
import { useState } from "react";

export default function MovieCard({ movie }) {
  const [isFavorit, setIsFavorit] = useState(movie.favorit);

  const handleClick = async () => {
    setIsFavorit(!isFavorit);
    await updateFavorit(movie.id, movie.favorit);
  };

  return (
    <div className="col-span-1 relative">
      {isFavorit ? (
        <button
          onClick={handleClick}
          className={`absolute top-2 right-2 z-20 fa-solid fa-heart text-red-500 text-3xl`}
        />
      ) : (
        <button
          onClick={handleClick}
          className={`absolute top-2 right-2 z-20 fa-regular fa-heart text-red-500 text-3xl`}
        />
      )}

      {/* image */}
      <div>
        <img src={movie.image_url} className="w-full" />
        <Link href={`/movies/${movie.id}`}>
          <div className="absolute flex items-center justify-center top-0 bottom-0 left-0 right-0 z-10 bg-black opacity-0 hover:opacity-80 transition-opacity duration-300">
            <p className="text-xl font-bold text-white">{movie.title}</p>
          </div>
        </Link>
      </div>
    </div>
  );
}

export async function updateFavorit(id, state) {
  const supabase = await createServerSupabaseClient();
  state = state == 1 ? 0 : 1;
  const { data, error } = await supabase
    .from("movie")
    .update({
      favorit: state,
    })
    .eq("id", id);
  handleError(error);

  return data;
}

 

 

[찜한 영화를 화면 최상단으로 보여주도록 정렬]

export default function MovieCard({ movie }) {
  return (
    <div className="col-span-1 relative">
      <button
        className={`absolute top-2 right-2 z-20 ${
          movie.favorit ? "fa-solid fa-heart" : "fa-regular fa-heart"
        } text-red-500 text-3xl`}
      />
      <div>
        <img src={movie.image_url} className="w-full" />
        <Link href={...}>
          <div className="absolute flex items-center justify-center top-0 bottom-0 left-0 right-0 z-10 bg-black opacity-0 hover:opacity-80 transition-opacity duration-300">
            <p className="text-xl font-bold text-white">{movie.title}</p>
          </div>
        </Link>
      </div>
    </div>
  );
}

 

풀스택 풀스택 워밍업

답변 0