View
개요
Next.js 12.1버전으로 개발했던 프로젝트를 13버전으로 업그레이드하면서 경험한 내용을 정리해 보았습니다.
얼마 전 Next.js 13.4가 릴리즈되면서 App Router의 안정화, Turbopack의 베타 버전 적용 등의 큼직한 변경점들이 있었습니다. 완전히 적용시키기에는 아직 이해가 부족한 부분이 있어서 일단 기존의 페이지 라우터 방식을 유지하면 점진적으로 업그레이드를 진행하려고 합니다.
먼저 새로워진 next/image, next/link 컴포넌트에 대한 변경사항에 대해 살펴보고, 프로젝트에 필요한 리팩토링도 진행해 보았습니다.
Command 실행하기
npm i next@latest react@latest react-dom@latest eslint-config-next@latest
# or
yarn add next@latest react@latest react-dom@latest eslint-config-next@latest
# or
pnpm up next react react-dom eslint-config-next --latest
# or
bun add next@latest react@latest react-dom@latest eslint-config-next@latest
Next.js 13에서는 노드 최소 버전 16.14.0 이상, React 최소 버전 18.2.0 이상으로 상향되었어요.
커맨드를 실행하여 React 버전을 업데이트하고, package.json에 해당 노드 버전 이상일 때 실행 가능하도록 명시하였습니다.
// package.json
{
...,
"engines": {
"node": ">=16.14.0"
},
"dependencies": {
"next": "^13.4.19",
"react": "^18.2.0",
"react-dom": "^18.2.0",
},
...
}
<Image/> Component 변경된 점
이전 버전의 next/image 컴포넌트를 사용하려면 이름이 변경된 next/legacy/image를 import해서 사용해야 합니다.
새로 업데이트된 next/image 컴포넌트에는 몇 가지 변경된 점들이 있습니다.
기존 Image 컴포넌트는 <span> 태그가 내부의 <img> 태그를 래핑하고 있는 형태로, <img> 태그에 바로 접근하는 것이 어려웠습니다. <span> 태그에 기본 스타일링이 되어 있어 커스텀 스타일을 추가하는데에 어려움을 겪기도 했습니다.
13버전에서는 <img>를 래핑하던 <span> 태그가 제거되었어요.
또한 기존 Image 컴포넌트에서는 layout 속성에 intrinsic(default), fixed, responsive, fill 값을 적용하여 뷰포트 크기가 리사이징될 때에 이미지 레이아웃의 동작을 설정했습니다.
새롭게 변경된 next/image 컴포넌트는 리사이징시에 기본적으로 정적으로 사이즈가 유지되고, 화면에 따라 가변적으로 변하도록 적용하려면 fill 속성을 true로 설정해주면 됩니다.
<Link /> Component 변경된 점
이전 버전의 next/link 컴포넌트를 사용하려면 legacyBehavior 속성을 true로 설정해야 합니다.
변경된 Link 컴포넌트에서는 더 이상 컴포넌트 내부에 <a>태그를 작성하지 않아도 됩니다.
새로운 next/link 컴포넌트는 <a> 태그를 완전히 대체가능하기 때문에 <a> 태그의 기본 속성이나 스타일을 props로 추가할 수 있습니다.
# before
<Link href="https://..." passHref>
<a>go to link</a>
</Link>
# after
<Link href="https://...">go to link</Link>
+ 리팩토링 진행하기
추가적으로 새롭게 추가된 기능은 아니지만, 기존에 next/router의 useRouter() hook을 사용해서 라우팅하고 있던 로직 일부를 next/link 컴포넌트를 통한 라우팅 방식으로 전환하는 작업을 진행했습니다.
# before
import { useRouter } from 'next/router';
const NavMenu: React.FC = () => {
const router = useRouter();
const moveToPageURL = (pageURL: string, target?: string) => {
if (target) {
window.open(pageURL, '_blank');
return;
}
router.push(pageURL);
};
return (
<ul>
<li onClick={() => moveToPageURL('/about')}>About</li>
<li onClick={() => moveToPageURL('/projects')}>Projects</li>
<li onClick={() => moveToPageURL('https://...', '_blank')}>Blog</li>
</ul>
);
};
# after
import Link from 'next/link';
const NavMenu: React.FC = () => {
return (
<div>
<Link href='/about'>About</Link>
<Link href='/projects'>Projects</Link>
<Link href='https://...' target='_blank'>Blog</Link>
</div>
);
};
next/link는 CSR 방식의 라우팅과 prefetch 기능을 제공하여 네트워크 요청을 줄이고 빠르게 라우팅할 수 있도록 도와줍니다. 하지만 useRouter()의 경우 기본적으로는 prefetch가 적용되지 않아 별도로 로직을 추가해 주어야 합니다.
useEffect(() => {
// Prefetch the dashboard page
router.prefetch('/dashboard');
}, [router]);
prefetch나 페이지 간 네비게이션을 쉽게 구현하고 싶다면 next/link를, 컴포넌트 내에서 라우팅 관련 추가 작업이 필요하다면 useRouter()를 사용하는 것이 유용할 것 같습니다.
참고
'Frontend > Next.js' 카테고리의 다른 글
Next.js On-Demand Revalidation 이해하기 (0) | 2023.05.16 |
---|---|
Next.js 개념 이해하기 (0) | 2022.09.14 |
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Total
- Today
- Yesterday
- React
- javascript
- mocking
- HTTP
- Promise
- Suspense
- 운영체제
- IntersectionObserverAPI
- react-query
- Network
- Next.js
- https
- MSW
- async-await
- d3