✍ 공부/NextJS

[ TIL ] Next.js에서 Link 사용하기

Po_tta_tt0 2022. 3. 21. 15:10
반응형

 

 

 

 

 

 

 

✍ React와 Next.js에서 <Link />란?

 

React에서 react-router-dom을 이용할 때도 Link 태그를 사용했었다.

 

: react-router-dom

<Link to="/about">About</Link>
<Link to="/courses?sort=name" />
<Link
  to={{
    pathname: "/courses",
    search: "?sort=name",
    hash: "#the-hash",
    state: { fromDashboard: true }
  }}
/>

 

익숙한 모습이다.

 

 

: Next.js

        <Link href="/">
          <a>Home</a>
        </Link>
          <Link href={`/blog/${encodeURIComponent(post.slug)}`}>
            <a>{post.title}</a>
          </Link>
        <Link
          href={{
            pathname: '/blog/[slug]',
            query: { slug: 'my-post' },
          }}
        >
          <a>Blog Post</a>
        </Link>

 

 

.

.

.

 

다른 점이 몇 개 있다.

그 중 하나가 바로 a 태그이다.

 

react에서는 페이지를 전환하는 과정에서 페이지를 불러오지 않고 페이지의 주소만 변경해야 하기 때문에 a 태그를 쓰지 않는다.

반면에 Next.js는 페이지 전환을 방지하는 Link 내에서 a 태그를 사용한다.

        <Link href="/">
          Home
        </Link>

Next.js Link 태그 안에 a 태그를 따로 쓰지 않더라도 HTML 마크업은 a 태그 안에 Home이 쌓여져 나온다

=> a 태그를 Link 안에 넣지 않아도 자동으로 a 태그가 생성된다.

 

 

 

 

 

 

 

 

Next.js에서 <Link /> 사용하기

 



href - 이동할 경로 혹은 URL. 유일한 필수 prop. (필수이기 때문에 href를 안 적으면 에러난다)
as - 브라우저 URL 표시 줄에 표시 될 경로에 대한 선택적 데코레이터. Next.js 9.5.3 이전에는 동적 경로에 사용되었으므로 이전 문서 에서 작동 방식을 확인하길 바란다.
passHref - href property를 Link 자식에게 강제로 전달하게 한다. 기본값은 false.
prefetch
 - 백그라운드에서 페이지를 미리 가져온다. 기본값은 true. <Link /> 뷰 포트에 있는 모든 항목(초기에 혹은 스크롤을 통해)이 미리 로드 된다. prefetch={false}를 통해 프리페치를 비활성화할 수 있다. 정적 생성을 사용하는 페이지는 더 빠른 페이지 전환을 위해 데이터가 포함된 JSON파일을 미리 로드한다.
replace - history 스택(방문 기록)에 새 url을 추가하는 대신 현재 상태를 변경한다. 기본값은 false
scroll - 페이지 전환 후 페이지 상단으로 스크롤할지 여부. 기본값은 true.
shallow - getStaticProps, getServerSideProps,  getInitialProps을 다시 실행하지 않고 현재 경로를 업데이트. 기본값은 false.

출처 : https://crong-dev.tistory.com/50

 

 

📌 Dynamic 경로일 경우

 

          <Link href={`/blog/${encodeURIComponent(post.slug)}`}>
            <a>{post.title}</a>
          </Link>
<Link
  href={{
    pathname: `/movies/${movie.id}`}}>

백틱( ` ) 과 ( ${ } )를 이용해 주면 된다

 

 

 

📌 Link의 자식이 <a> 태그로 감싸져 있을 경우

 

passHref를 꼭 추가해주어야 한다.

import Link from 'next/link'
import styled from 'styled-components'

// This creates a custom component that wraps an <a> tag // ✨ 1
const RedLink = styled.a`
  color: red;
`

function NavLink({ href, name }) {
  // Must add passHref to Link 
  return (
    <Link href={href} passHref> // ✨ 2
      <RedLink>{name}</RedLink> // ✨ 1
    </Link>
  )
}

export default NavLink

✨ : 봐야 할 곳 표시

 

1. 을 보면 Link의 자식으로 styled component를 사용하고 있다.

2. 이 때 꼭 passHref 속성을 써주고 있다 ( 꼭 이 경우가 아니라도 명시해주는게 좋다 )

 

 

이유

  • passHref가 빠진 link의 <a> 태그로 쌓여진 자식 컴포넌트는 HTML 마크업 시 href 속성이 사라지게 된다
  • 따라서 새 창에서 열리지 않는다 => UX에 좋지 않다
  • 검색엔진이 읽을 수 있는 href 속성이 없기 때문에 검색엔진이 추적할 수 없는 링크가 된다.

 

 

 

 

📌 자식 컴포넌트가 함수형일 경우

함수 컴포넌트는 ref가 존재하지 않는다.

따라서 자식이 함수형일 경우 함수형인 자식 컴포넌트로 ref를 전달해야 한다.

=> React.forwardRef 이용

 

import Link from 'next/link'

// `onClick`, `href`, and `ref` need to be passed to the DOM element
// for proper handling
const MyButton = React.forwardRef(({ onClick, href }, ref) => { // ✨ 2
  return (
    <a href={href} onClick={onClick} ref={ref}>
      Click Me
    </a>
  )
})

function Home() {
  return (
    <Link href="/about" passHref> // ✨ 1
      <MyButton />
    </Link>
  )
}

export default Home

1. 함수형인 자식 컴포넌트를 가진 Link에 passHref 속성을 추가한다

2. 함수형인 자식 컴포넌트에 React.forwardRef을 추가하여 ref를 전달받는다

 

 

 

 

 

📌 URL 객체를 사용할 경우

import Link from 'next/link'

function Home() {
  return (
    <ul>
      <li>
        <Link // ✨ 1
          href={{
            pathname: '/about',
            query: { name: 'test' },
          }}
        >
          <a>About us</a>
        </Link>
      </li>
      <li>
        <Link // ✨ 2
          href={{
            pathname: '/blog/[slug]',
            query: { slug: 'my-post' },
          }}
        >
          <a>Blog Post</a>
        </Link>
      </li>
    </ul>
  )
}

export default Home

 

1. 정의된 시멘틱 경로 : /about?name=test

2. 다이나믹 경로(동적 경로): /blog/my-post

 

 

 

+

<Link
            href={{
              pathname: `/movies/${movie.id}`,  //✨ 경로
              query: {
                title: movie.original_title, //✨ 전달하는 query
              },
            }}
            as={`/movies/${movie.id}`} // ✨ 유저에게 보여지는 주소창
            key={movie.id} // ✨ map으로 감쌌기 때문에 사용하는 key
          >

 

 

 

 

 

 

 

🙇‍♀️ SUPER THANKS

https://nextjs.org/docs/api-reference/next/link

https://v5.reactrouter.com/web/api/Link

https://uchanlee.dev/nextjs/Why-using-a-tag-in-nextjs-Link/

https://f-dever-error-log.tistory.com/56

https://salgum1114.github.io/nextjs/2019-05-24-nextjs-static-website-4/

https://crong-dev.tistory.com/50

 

 

 

 

 

 

반응형