꾸준히 성장하는 개발자

[Next.js] Louting 본문

Next.js

[Next.js] Louting

ahleum 2022. 5. 31. 20:15

a태그로 페이지 이동이 가능하나 빨간 줄이 쳐져 있는 것을 볼 수 있다.

a태그로 한다고 해서 작동이 안 되는 것은 아니나 

페이지가 넘겨질 때마다 전체 페이지가 새로고침이 되는 것을 볼 수 있다.

그만큼 속도는 좀 더 느려진다

 

 

 

에러 메시지를 보면 next/link의 Link를 사용하라고 나온다

그대로 바꿔보게 되면 아래처럼 바꿔줄 수 있다.

import Link from "next/link";

export default function NavBar() {
  return (
    <nav>
      <Link href="/">
        <a>Home</a>
      </Link>
      <Link href="/About">
        <a>About Us</a>
      </Link>
    </nav>
  );
}

React에서는 <a> 태그 없이 <Link> 로만도 사용이 가능한데

Next.js 도 만약 저 안에 <a> 태그를 안 쓴다면 어떨까?

 

 

그래도 작동은 된다.

하지만 단점이 이 Link에 무언가를 전달할 수는 없다는 점이다

 

예를 들어 style이나 class를 넣어줘도 실행이 되지 않는다

<Link>는 오직 href를 위한 거라고 보면 된다

만약 위의 속성들을 넣고 싶다면???

<a> 태그에 넣어주면 된다. 

 

 

a태그를 넣어주고 a태그에 위의 속성들을 넣어주자 실행이 되는 것을 볼 수 있다.

 


 Hook useRouter

import { useRouter } from "next/router";

export default function NavBar() {
  const router = useRouter();
  console.log(router);
  return (
    <nav>
      <Link href="/">
        <a style={{ color: router.pathname === "/" ? "red" : "blue" }}>
          Home
        </a>
      </Link>
      <Link href="/About">
        <a style={{ color: router.pathname === "/About" ? "red" : "blue" }}>
          About Us
        </a>
      </Link>
    </nav>
  );
}

console.log(router)를 쳐보면 위처럼 나오는 것을 확인할 수 있는데 어떻게 이용할 수 있을까?

 

내가 이 페이지에 있다면 색상을 위처럼 바뀌게 하면서 확인할 수 있다.

 

 

 


만약 아래와 같이 되어 있다면 a태그 안에 div태그가 있는 것은 맞지 않는 것 같다. 

그렇다고 문자들만 a태그로 감싼다면 포스터를 눌러도 페이지 이동이 되지 않을 것이다. 

하지만 아래처럼 그림처럼 포스터와 제목 중 어느 것을 클릭해도 페이지가 이동해지도록 하길 원한다면???

export default function Home({ results }) {
  return (
      {results?.map((movie) => (
        <Link href={`/movies/${movie.id}`} key={movie.id}>
          <a>
            <div className="movie">
              <img src={`https://image.tmdb.org/t/p/w500${movie.poster_path}`} />
              <h4>{movie.original_title}</h4>
            </div>
          </a>
      </Link>
    ))}
 );
}

 

export default function Home({ results }) {
// router hook을 이용하여 div태그가 클릭이 되었을때 함께 넘어가게 해줄수 있다.
  const router = useRouter();
  const onClick = (id) => {
    router.push(`/movies/${id}`);
  };
  return (
      {results?.map((movie) => (
        <div className="movie" onClick={() => onClick(movie.id)} key={movie.id}>
          <img src={`https://image.tmdb.org/t/p/w500${movie.poster_path}`} />
          <h4>
            <Link href={`/movies/${movie.id}`}>
              <a>{movie.original_title}</a>
            </Link>
          </h4>
        </div>
      ))}
  );
}

 

 

 

위에서 router를 이용해서 다양한 정보를 보내줄 수 있는 방법을 알아보자

 

// case 1
const router = useRouter();
  const onClick = (id) => {
    router.push(`/movies/${id}`);
  };
  
  
  // case 2
  const router = useRouter();
  const onClick = (id, title) => {
    router.push(
      {
        pathname: `/movies/${id}`,
        query: {
          id,                       // 이렇게 객체형태로도 전달이 가능하고 이 내용들이
          title,                    // url에 같이 담겨서 넘어가진다. 
        },
      });
  };
  
  
  // case 3
  const router = useRouter();
  const onClick = (id, title) => {
    router.push(
      {
        pathname: `/movies/${id}`,
        query: {
          id,
          title,
        },
      },
       `/movies/${id}`  // 이렇게 넣어주면 사용자들에게 보여주는 url은 여기까지만 나오고 
    );                  // query에 위 내용들이 같이 담겨서 페이지 이동이 된다.
  };

case 2 로 바꾸게 되었을때 url 상태
case 2 로 바꾸게 되었을때 url 상태와 console에 찍힌 query

 

 

위 case 2,3으로 바뀌었다면 안에 Link의 href도 같은 방식으로 바꿔본다면

아래와 같이 바꿔볼 수 있을 것이다.

          <Link
              href={{
                pathname: `/movies/${movie.id}`,
                query: {
                  title: movie.original_title,
                },
              }}
              as={`/movies/${movie.id}`}
            >
              <a>{movie.original_title}</a>
            </Link>