Front-End(Web)/React - 프레임워크(React, Next)

[Next.js] next/link - <Link> 태그

ttaeng_99 2022. 10. 3. 14:20
반응형

🤔 서론

본래는, Next 스터디를 진행하면서 <Link>에 Styled-Components를 적용하며 겪었던 이슈를 정리하려는 포스팅이었다.

그런데, Next를 처음 공부할 때에도 next/link를 정리한 적이 없어 이번 기회에 한 번 전체적으로 제대로 공부해보고자 한다!

 


 

🤍 next/link 및 <Link> 태그

Next.js에서 페이지 간의 링크전환에 <Link> 태그를 주로 사용한다.

페이지 리렌더링 없이 이동시켜주는 SPA 동작을 담당하며, <a> 태그로 전환되어 SEO에 적합하거나 다음 페이지를 prefetch 하는 등의 장점이 있다.

 

그렇기에 네비게이션 바에서 많이 볼 수 있으며, 아래와 같이 사용될 수 있다.

(pages 폴더 내 index.tsx, about/index.tsx, blog/[slug].tsx 세 가지 페이지에 대한 라우팅을 제공하는 예시)

import Link from 'next/link'

function Navbar() {
  return (
    <ul>
      <li>
        <Link href="/">
          <a>Home</a>
        </Link>
      </li>
      <li>
        <Link href="/about">
          <a>About Us</a>
        </Link>
      </li>
      <li>
        <Link href="/blog/hello-world">
          <a>Blog Post</a>
        </Link>
      </li>
    </ul>
  )
}

위처럼, <Link> 태그를 사용하고 href로 이동할 path를 지정하면 <a> 태그와 유사하게 동작한다. <Link> Props는 아래가 있다.

  • href : 이동할 경로 혹은 URL (필수값이므로 누락 시 에러 발생)
  • as : 브라우저 URL 표시줄에 노출될 경로에 대한 선택적 데코레이터 (Next.js 9.5.3 전에는 동적경로로 사용됨)
  • passHref : href 프로퍼티를 <Link> 자식에게 강제로 전달. 기본값은 false.
  • prefetch : 뷰포트에서 경로에 해당하는 페이지들을 백그라운드에서 미리 가져온다. 기본값은 true.
  • replace : history 스택(방문기록) 마지막 기록을 현재 페이지로 대체한다. 기본값은 false.
  • scroll : 페이지 전환 후 상단으로 스크롤할지 여부. 기본값은 true.
  • shallow : SSR을 다시 실행하지 않고 현재 경로를 업데이트. 기본값은 false.
  • locale : 링크에 locale을 추가해준다. (Next 10부터 추가)

 

<Link> 태그는 웹에서 렌더링 될 때는 <a> 태그로 전환된다. 

 

 

- Dynamic Routes(동적 경로)로 이동

import Link from 'next/link'

function Posts({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>
          <Link href={`/blog/${encodeURIComponent(post.slug)}`}>
            <a>{post.title}</a>
          </Link>
        </li>
      ))}
    </ul>
  )
}

export default Posts

Next.js 9.5.3 이후 동적경로에 연결할 때 특별히 해야할 일이 없다. (경로를 캐치하는 등)

하지만, 보간(interpolation)이나 URL 객체로 링크를 생성하는 것은 권장하는 편이라고 한다.

 

 

- 자식이 <a> 태그로 감싸진 커스텀 컴포넌트인 경우

어떻게 보면 이 포스팅을 정리하게 된 시발점이라고 할 수 있겠다.

Styled-Compoents로 스타일하는 경우 React-Router 에서는 <Link> 태그를 styled(Link)로 커스텀이 가능했으나, Next.js는 이를 지원하지 않았다.

 

그렇기에, 내부에 <a> 태그 기반의 Styled-Components를 넣고 여기에 passHref로 링크를 전달해주는 게 일반적이다.

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

const RedLink = styled.a`
  color: red;
`

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

export default NavLink

passHref를 전달하지 않으면 Shift or Ctrl + 클릭이 되지 않아 UX에 좋지 않으며, <a> 태그에 href가 없어 SEO 손상이 될 수 있다. 

* 참고 : emotion의 JSX Pragma(@jsx jsx)를 사용한다면, <a> 태그를 직접 사용하더라도 passHref가 필요

 

 

- 자식이 함수형 컴포넌트인 경우

import Link from 'next/link'

const MyButton = React.forwardRef(({ onClick, href }, ref) => {
  return (
    <a href={href} onClick={onClick} ref={ref}>
      Click Me
    </a>
  )
})

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

export default Home

<Link> 내부에 함수형 컴포넌트가 적용된 경우, passHref와 더불어 forwardRef() 로 자식 컴포넌트를 감싸야한다.

* forwardRef() 참고 링크 : https://abangpa1ace.tistory.com/270

 

[React] 자식 컴포넌트 제어 - forwardRef, useImperativeHandle

사이드 프로젝트에서 Uncontrolled Input을 구현하기 위해 고민하던 중, 문득 자식(input)의 ref.current.value를 부모(container component)가 어떻게 참조할 수 있을까에 대한 의문이 생겼다. * ref, useRef()..

abangpa1ace.tistory.com

 

 

- URL 객체 사용

<Link> 또한 URL 객체를 받을 수 있다. pathname, query 등 객체를 통해 URL 문자열이 생성될 수 있다.

import Link from 'next/link'

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

export default Home

예제는 각각 /about?name=test, /blog/my-post 경로로 파싱된다. Node.js URL 모듈정의의 모든 속성을 사용 가능하다.

 


 

정말 간단하게 정리가 끝났다. 내용 자체는 많지 않지만 관습적으로 많이 쓰는 <Link>의 숨은 장점들을 많이 발견하였다.

 

as, replace 등으로 url 커스텀이 가능할 뿐 아니라, locale이 Next.js 10에 추가되어 다국어 대응에도 유용함을 느꼈다.

<Link> 내에 Styled-Components나 함수 컴포넌트를 적용하는 경우도 종종 있으니 passHref, forwardRef 등을 감안해서 작업하도록 해야겠다!

 

 

🧷 출처

- [next/link 개념] Next.js 공식문서 : https://nextjs.org/docs/api-reference/next/link

- [next/link 개념] Next.js 공식문서(번역) : https://crong-dev.tistory.com/50

 

- [next/link 참고] f-dever-error-log 님의 블로그 : https://f-dever-error-log.tistory.com/56

반응형