ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Next.js] next/link - <Link> 태그
    Front-End(Web)/React - 프레임워크(React, Next) 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

    반응형
Designed by Tistory.