게으른개발너D
Framework Overview 2 - Static Pre Rendering and Routing 본문
1. Static Pre Rendering
next.js의 가장 좋은 기능 중 하나는, 앱에 있는 페이지들이 미리 렌더링 (Pre-Rendering)된다는 점이다.
이것들은 정적 (static)으로 생성된다.
1.1 create-react-app과 next.js의 차이점
create-react-app
create-react-app은 client-side render를 하는 앱을 만든다.
client-side render는 우리 브라우저가 유저가 보는 UI를 만드는 모든 것을 한다는 것을 의미한다.
예를들어 create-react-app으로 만든 우리 프로젝트를 살펴보면 header, menu, card 등 다양한 것들이 많은데, 걔네들은 유저가 보는 HTML 소스코드 안에 들어있지 않다. 소스 코드를 살펴보면 아래처럼 div 하나만 나와있을 것이다.
<div id="root"></div>
브라우저가 react.js를 다운받고 우리 코드를 다운 받았을 때, 그때 react.js는 다른 모든 것들을 렌더링하고 유저는 header나 menu같은 것들을 보게되는 것이다.
브라우저가 JS를 요청하고 client-side의 JS가 모든 UI를 만들게 된다.
만약 브라우저가 느리다면 브라우저가 JS파일을 요청하고 다운받기 전 화면이 나오므로 하얀화면이 나오게 될 것이다.
자바스트립트가 disabled 될때도 마찬가지이다.
next.js
next.js는 pre-render를 한다.
javascript를 비활성화하고 next.js로 만든 프로젝트 페이지를 새로고침 시켜보자.
next.js의 소스코드를 보면 소스코드 어딘가에 우리가 구현한 HTML이 있는걸 볼 수 있다.
유저의 브라우저가 매우 느린 연결을 하고 있거나 JS가 완전히 비활성화 되어있어도 유저는 HTML을 볼 수 있다.
api로 가져오는 데이터가 로딩되는 데에는 오랜 시간이 걸릴 수도 있지만 유저는 적어도 어떠한 HTML은 볼 수 있다.
우리가 js로 어떤 active를 하여 화면의 요소가 변경 된 후 소스코드를 보면 변경된 요소 대신 초기상태의 요소가 적용되어있다.
이렇게 next.js는 초기 상태로 pre-rendering을 한다. 그리고나서 react.js가 (클라이언트로) 전송되었을 때 react.js 앱이 된다.
react.js를 프론트엔드 안에서 실행하는 것을 hydration이라고 부른다.
왜냐면 next.js는 react.js를 백엔드에서 동작시켜서 페이지를 미리 만드는데, 렌더링이 끝났을 때 코드는 HTML이 되고 next.js는 그 HTML을 페이지의 소스코드에 넣어준다.
그럼 유저는 js와 react.js가 로딩되지 않더라도 콘텐츠를 볼 수 있게 된다.
pre-rendering이 짱인 점은 SEO에 좋다는 점이다. 유저들이 우리 웹사이트에 오면 이미 무언가가 있기 때문이다.
2. Routing
2.1 link의 잘못된 예
네비게이션 컴포넌트를 만들어보자.
components 폴더 안에 NavBar.js 파일을 만들자.
// NavBar.js
function NavBar() {
return <nav>
<a href="/">Home</a>
<a href="/about">About</a>
</nav>
}
export default NavBar;
그리고 index.js와 about.js에 위의 컴포넌트를 추가해 준다.
// index.js
import NavBar from "../components/NavBar";
function Home() {
return <div>
<NavBar />
<div>Hello</div>
</div>
}
export default Home;
이제 navbar에 있는 링크를 클릭해 주면 해당 링크가 가리키는 페이지로 이동하게 된다.
그런데 NavBar 컴포넌트를 보면 a 코드쪽에 ESLint 에러가 발생하고 있다.
메세지를 보면 a 태그를 Home페이지로 이동하는데 사용하지마라고 적혀있다.
next.js 어플리케이션에서 anchor 태그를 네비게이팅하는 데에 사용하면 안되는 이유는 next.js에 앱 내에서 페이지를 네비게이트할 때 사용해야만 하는 특정 컴포넌트가 존재하기 때문이다.
react.js에서 React Router Link를 사용해야만 할 때와 이유가 같다.
만약 a태그로 페이지 이동을 한다면 페이지가 리로드되게 된다. 이 뜻은 브라우저가 다른 페이지로 보내기 위해 전체 페이지를 새로고침한다는 뜻이다.
2.2 Link component
위의 메세지를 읽어보면 next/link로부터 임포트되는 Link 컴포넌트를 사용하라고 되어있다.
Link는 우리에게 next.js 어플리케이션의 클라이언트 사이드 네비게이션을 제공해준다.
NavBar.js를 아래와 같이 수정해주자.
// NavBar.js
import Link from 'next/link';
function NavBar() {
return <nav>
<Link href="/"><a>Home</a></Link>
<Link href="/about"><a>About</a></Link>
</nav>
}
export default NavBar;
a 태그를 Link로 감싸주고 href attribute는 Link 컴포넌트 안에 넣어준다.
이제 화면에서 navbar의 링크를 클릭하면 리로딩되는 것 없이 화면이 빨리빨리 전환된다.
Link 안에 a 태그를 넣는 것처럼 react router dom에서 처럼 Link 안에 바로 Home 글자를 넣을 수도 있다.
하지만 next/link에서 제공하는 Link 컴포넌트에 style이나 className같은 것을 적용시킬 수 없다.
Link는 오직 href를 위한 것이다.
cf)
https://nextjs.org/docs/messages/invalid-new-link-with-extra-anchor
next.js 13버전부터는 Link 안에 a 태그를 넣으면 에러가 나도록 되어있다.
$npx @next/codemod new-link .
새로운 Link 컴포넌트를 사용할 수 있도록 위의 명령어를 입력하여 업데이트 시켜주자.
// <Link href="/">
// <a id="hi">Hi</a>
// </Link>
<Link href="/" id="hi">Hi</Link>
그럼 위의 주석처리된 코드를 아래처럼 사용할 수 있다.
2.3 router
이제 어떠한 hook을 사용하여 라우터와 연결해보자.
바로 next.js에 있는 useRouter 훅을 사용할 것이다.
// NavBar.js
import Link from 'next/link';
import { useRouter } from 'next/router';
function NavBar() {
const router = useRouter();
return <nav>
<Link href="/"><a>Home</a></Link>
<Link href="/about"><a>About</a></Link>
</nav>
}
export default NavBar;
보다시피 모든 게 이미 install되어 있으니 그냥 갖다 쓰기만 하면 된다.
package.json을 보면 dependencies도 매우 적다.
갖고 있는 전부가 next와 react, react-dom이다.
react-router-dom을 install할 필요도 없다 그 외 웬만한건 뭐든 install할 필요가 없다.
위 코드에서 선언한 router를 console.log로 찍어보자.
asPath, back, basePath, pathname같은 우리 location에 관한 정보들을 얻을 수 있다.
해당 정보들을 이용하여 우리가 현재 home에 있는지 about에 있는지 알아보자.
a 태그에 style을 추가하자.
// NavBar.js
import Link from 'next/link';
import { useRouter } from 'next/router';
function NavBar() {
const router = useRouter();
return <nav>
<Link href="/">
<a style={{ color: router.pathname === '/' ? 'red' : 'blue' }}>Home</a>
</Link>
<Link href="/about">
<a style={{ color: router.pathname === '/about' ? 'red' : 'blue' }}>About</a>
</Link>
</nav>
}
export default NavBar;
index 페이지에 접속하면 Home 링크가 빨간색으로 변하고 about 페이지에 접속하면 About 링크가 빨간색으로 변하게 된다.
출처
노마드코더
'개발 > NextJS' 카테고리의 다른 글
Practice Project 2 - Server Side Rendering (0) | 2023.11.30 |
---|---|
Practice Project 1 - Patterns and Redirect, Rewrite (1) | 2023.11.28 |
Framework Overview 3 - Styles and Custom App (1) | 2023.11.23 |
Framework Overview 1 - Framework and Pages (0) | 2023.04.25 |
Creating a Project (ver. 13) (0) | 2023.04.25 |