✍ 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
'✍ 공부 > NextJS' 카테고리의 다른 글
[ TIL ] Next.js 동적 라우팅 ( Dynamic Routing ) (0) | 2022.03.19 |
---|---|
[ TIL ] Next.js redirects와 rewrites로 API key 숨기기 (0) | 2022.03.18 |
Next.js에서 .env 사용하기 (2) | 2022.03.18 |
[ Next.js ] SSR , CSR 그리고 SEO (0) | 2022.03.17 |
[ TIL ] 노마드코더 NextJS #2.0 - #2.1 (0) | 2022.03.16 |