[NextJS] Mini_project_4

신치우·2023년 4월 27일
0

NextJS

목록 보기
6/11

dynamic URL을 만들어보자


pages 폴더 안에 만들어주면 끝!
1. movies\all.js --> xxxxx/movies/all
2. movies\index.js --> xxxxx/movies
3. about.js --> xxxxx/about
4. indes.jx --> xxxxx/

URL에 변수를 넣는 방법

이렇게 해주면 끝!
movies/1111111 <-- 1111111 이게 ID!

import { useRouter } from "next/router";

export default function Detail() {
  const router = useRouter();
  console.log(router);
  
    return "detail";
}

page detail을 만들어보자

나는 아래와 같이 코드를 작성하였는데 정상적으로 동작을 한다

{results?.map((movie) => (
        <Link legacyBehavior href={`/movies/${movie.id}`} key={movie.id}>
          
            <div className='movie'>
              <img src={`https://image.tmdb.org/t/p/w200${movie.poster_path}`} />
              <h4>{movie.original_title}</h4>
            </div>
          
        </Link>
      ))}

그런데 노마드코더에서 나오는 것은 구버전이기 때문에 위와같이 작성하면 동작하지 않는다.
1. 일단 Link 안에 <a> tag를 써서 동작을 하는버전
2. <a> tag를 사용하면 태그 안에 텍스트만 쓰는 것을 추천하는 문제 (이러면 이미지는?)
3. 그로 인해 text와 이미지에는 다른 방법을 적용해야 한다
아래처럼

  const onClick = (id) => {
    router.push(`/movies/${id}`);
  }

{results?.map((movie) => (
          <div onClick={() => onClick(movie.id)} className='movie' key={movie.id}>
            <img src={`https://image.tmdb.org/t/p/w200${movie.poster_path}`} />
            <h4>
              <Link legacyBehavior href={`/movies/${movie.id}`}>
              {movie.original_title}
              </Link>
            </h4>
          </div>
      ))}

위 코드를 보면 text에 Link를 따로 설정하고 img 클릭시 이동할수 있게 onClick으로 설정해준 것을 볼 수 있다.

NextJS 버전이 업데이트 되서 Link가 참 편해졌다고 생각했다
하지만 위 방법도 기억을 해놔야할 것 같다(생각해보니 그냥 React랑 같은거 아닌가..?)

이제는 영화를 클릭하면 해당 영화 정보로 이동되게 해보자

먼저 API를 받아오면서 + 숨기기 위해 rewrite에 작성을 추가하자

async rewrites() {
    return [
      {
        source: '/api/movies',
        destination: `https://api.themoviedb.org/3/movie/popular?api_key=${API_KEY}`,
      },
      {
        source: '/api/movies/:id',
        destination: `https://api.themoviedb.org/3/movie/:id?api_key=${API_KEY}`,

      }
    ];
  }

그리고 router를 수정해주자

const onClick = (id) => {
    router.push({
      pathname: `/movies/${id}`,
      query:{
        title: 'hello',
      }
    });
  }

이렇게 수정을 해주고 영화를 클릭해서 들어가면

위 이미지처럼 URL이 바뀐것을 볼 수 있다
하지만 우리는 뒤에 ?title=hello 를 숨길수도 있다

  const onClick = (id) => {
    router.push({
      pathname: `/movies/${id}`,
      query:{
        title: 'hello',
      }
    }, `/movies/${id}`);
  }

이렇게 as를 사용하면 숨겨진다

그리고 이제 Detail page에서 영화 제목을 직접 띄울거다

const onClick = (id, title) => {
    router.push({
      pathname: `/movies/${id}`,
      query:{
        title: title,
      }
    }, `/movies/${id}`);
  }

<div onClick={() => onClick(movie.id, movie.original_title)} className='movie' key={movie.id}>

위에처럼 index.js 를 수정하고
아래처럼 [id].js 를 수정한다

import { useRouter } from "next/router";

export default function Detail() {
  const router = useRouter();
  console.log(router);
  
    return (
        <div>
            <h4>{router.query.title || "Loading..."}</h4>
        </div>

    );
}

그러면 Loading이 나오거나 아니면 title 이 나온다
문제가 있어어어어어
얘는 순서대로 접속을 해야만 정상동작한다
그말은
Home --> Detail로 움직여야만한다
한번에 바로가면 동작을 안한다

왜냐면 query가 없어서!!!!!!!!!!!
일단은 다음걸로 넘어간다..?

URL에 숫자(id) 대신 영화 제목이 뜨게 해보자 (cathAll URL을 만들자)

먼저 이제는 URL에 영화제목이 뜨게 할거야
그러기 위해서 우리가 할건
앞서 만들어놨던 [id].js의 파일명은 [...id].js로 바꾸기만 하면된다!
근데 나는 영상을 다 보고 정리하는거여서..
(query안에 있는 params를 쓰기 위해 이름이 params로 바뀜)

http://localhost:3000/movies/Ant-Man%20and%20the%20Wasp:%20Quantumania/640146
이러면 위와 같은 URL을 갖는 것을 볼 수 있다
이때 중간 작업으로 ID와 Movie.title의 순서를 바꾸는 부분이 들어간다

    <div className='container'>
      <HeadTitle title="Home" />
      {results?.map((movie) => (
        // <Link legacyBehavior href={`/movies/${movie.id}`} key={movie.id}>
        //     <div className='movie'>
        //       <img src={`https://image.tmdb.org/t/p/w200${movie.poster_path}`} />
        //       <h4>{movie.original_title}</h4>
        //     </div>
        // </Link>
          <div onClick={() => onClick(movie.id, movie.original_title)} className='movie' key={movie.id}>
            <img src={`https://image.tmdb.org/t/p/w200${movie.poster_path}`} />
            <h4>
              <Link legacyBehavior href={`/movies/${movie.original_title}/${movie.id}`}>
              {movie.original_title}
              </Link>
            </h4>
          </div>
      ))}
      
   const onClick = (id, title) => {
    router.push( `/movies/${title}/${id}`);
  }    

이러면 원하는 URL 모양으로 출력이 끝!

그리고 앞서 발생했던 URL로 직접 접근시 Loading이 뜨는 문제를 해결해보자
우리는 문제를 해결하기 위해서 앞에서 배운 sever side rendering을 사용할 것이다
[...params].js

import HeadTitle from "@/components/headTitle";

export default function Detail({params}) {
  const [title, id] = params || [];
    return (
        <div>
            <HeadTitle title={title}/>
            <h4>{title || "Loading..."}</h4>
        </div>

    );
}

export function getServerSideProps({params:{params}}) {

    return {
        props: {
            params,
        },
    };
}

위에서 보이는 것처럼 server 에서 미리 redering을 해놓고 있으면 언제 어디로 접근하더라도 해당 page를 볼 수 있게 된다!
따로 fetch를 할 필요도 없음
이미 우리는 index.js에서 fetch를 해서 해당 정보를 다 가지고 있으니깐!

profile
하루에 집중을

1개의 댓글

comment-user-thumbnail
2024년 2월 13일

The film's portrayal of the protagonist's growth and the adventures they encountered provided moments of wonder and inspiration. The heartwarming https://kinogobiz.online/ story and stunning visuals made the experience a joyful and magical escape. By the end, I was left humming the tunes and feeling uplifted.

These films offered a range of genres and themes, showcasing the variety of experiences available on streaming sites. Whether it was a haunting supernatural thriller, a refreshing rom-com road trip, a gripping documentary series, or a magical animated musical, each movie provided a unique and enriching journey.

답글 달기