Nextjs 기본
NextJS 란?
(리액트는 라이브러리, Next.js는 프레임워크이다. )
React의 SSR(Server Side Rendering)을 쉽게 구현할 수 있게 도와주는 간단한 프레임워크이다. 리액트로 개발할때 SPA을 이용하며 CSR(Client Side Rendering)을 하기때문에 좋은점도 있지만 단점도 있다. 검색엔진최적화(SEO)에 취약하다는 것이다. CSR을 하면 첫페이지에서 빈 html을 가져와서 JS파일을 해석하여 화면을 구성하기때문에 포털검색에 거의 논출될 일이 없다.(크롤링 안됨)
하지만 Next.js에서는 Pre-Rendering을 통해서 페이지를 미리 렌더링하며 완성된 HTML을 가져오기 때문에 사용자와 검색엔진 크롤러에게 바로 렌더링된 페이지를 전달 할 수 있게 된다.
리액트에서도 SSR를 지원하지만 구현하기에 굉장히 복잡하기 때문에 Next.js를 통해서 이문제를 해결할 수 있다.
Server Side Rendering
- 클라이언트 대신 서버에서 페이지를 준비한 원리.
- 원래 리액트에서는 CSR을 하기때문에 서버에 영향을 미치지 않고, 서버에서 클라이언트로 응답해서 보낸 html도 거의 비어있다.
👉 이 방식은 서버에서 데이터를 가져올 때 지연 시간 발생으로 UX 측면에서 좋지 않을 수 있다.
👉 검색엔진에 검색 시 웹 크롤링이 동작할 때 내용을 제대로 가져와 읽을 수 없기에 SEO에 문제가 됨. - Next.js에서는 SSR을 이용하므로 사용자와 검색엔진 크롤러에게 바로 렌더링이 된 페이지를 전달 할 수 있어서 UX, SEO에 좋은 영향을 준다.
설치 방법
npx create-next-app@latest
yarn create next-app
npx create-next-app ./ --typescript
타입스크립트 템플릿 사용
NextJS 기본 파일 구조
pages
- 이 폴더 안에 페이지 생성
index.ts
가 처음 "/" 페이지_app.tsx
는 공통되는 레이아웃을 작성함. 모든 페이지에 공통으로 들어가는 걸 넣어주려면 여기에 넣는다. url을 통해 특정 페이지에 진입하기 전 통과하는 인터셉터 페이지다.- 만약 about이라는 페이지를 만드려면 pages안에 about.tsx를 생성.
public
- 이미지같은 정적static 에셋 보관
styles
- 스타일링 처리해주는 폴더
next.config.js
- Nextjs는 웹팩을 기본 번들러로 사용
- 그래서 웹팩에 관한 설정들을 이파일에서 해줄 수 있다.
Pre-rendering
NextJS는
모든 페이지를 pre-render한다.
pre-render 테스트 하는방법
- 자바스크립트 Disable 자바스크립트 disable 방법
Ctrl+Shift+P
를 눌러 javascript검색후 disable명령어 실행(클릭)
주소표시줄에 다음 마크와 Sources패널에 javascript is disabled라고 뜨는지 확인한다.
- 보통 React사이트 들어가기
테스트용 리액트 기본 사이트 - Next.js 사이트 들어가기
테스트용 NextJS 기본 사이트
Data Fetching
NextJS에서 데이터를 가져오는 방법은 여러가지가 있다.
보통 리액트에서 데이터를 가져올때 useEffect안에서 가져온다. 하지만 Nextjs에서는 다른방법을 사용해서 가져온다.
- getStaticProps: Static Generation으로 빌드할때 데이터를 불러온다.
- getStaticPaths: Static Generation으로 데이터에 기반하여 pre-render시 특정한 동적 라우팅 구현(
pages/post/[id].js
) - getServerSideProps: SSR로 요청이 있을때 데이터를 불러온다.
getStaticProps
getStaticProps 함수는 페이지의 리퀘스트 경로에 따라 데이터를 가져옵니다. 따라서, 페이지별로 다른 데이터를 가져올 수 있습니다.
import React, { useState } from 'react';
const MyPage = ({ data }) => {
const [name, setName] = useState('');
if (data) {
name = data.name;
}
return (
<div>
<h1>My Page</h1>
<p>Name: {name}</p>
</div>
);
};
// getStaticProps 함수를 사용하여 데이터를 가져옵니다.
export const getStaticProps = async () => {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
return {
props: {
data,
},
};
};
export default MyPage;
getStaticProps를 사용해야할 때
- 페이지를 렌더링하는 데 필요한 데이터는 사용자의 요청보다 먼저 build시간에 필요한 데이터를 가져올 때
- headless CMS에서 데이터를 가져올 때
- 데이터를 공개적으로 캐시할 수 있을 때(사용자별 아님)
- 페이지는 미리 렌더링되어야 하고(SEO의 경우) 매우 빨라야할 때.(getStaticProps는 성능을 위해 CDN에서 캐시할 수 있는 HTML 및 JSON 파일을 생성한다.)
getStaticPaths
getStaticPaths 함수는 페이지의 리퀘스트 경로와 함께 데이터의 경로를 정의한다. 따라서, 페이지별로 다른 데이터를 가져오거나, 데이터를 캐싱할 수 있습다.
- 동적 라우팅이 필요할 때 getStaticPaths로 경로 리스트 정의, HTML에 build시간에 렌더링
- Nextjs는 pre-render에서 정적으로 getStaticPaths에서 호출하는 경로를 가져온다.
paths
어떠한 경로가 pre-render될 지 결정한다.
만약 pages/posts/[id].js
라는 이름의 동적 라우팅을 사용하는 페이지가 있다면 아래와 같이 된다.
return {
paths: [
{ params: {id: '1'} },
{ params: {id: '2'} },
],
fallback: ...
}
params
- 페이지 이름이
pages/posts/[postId]/[commentId]
라면, params는 postId와 commentId - 만약 페이지 이름이
pages/[...slug]
와 같이 모든 경로를 사용한다면, params는 slug가 담긴 배열이어야한다.['postId', 'commentId']
fallback
- false라면 getStaticPaths로 리턴되지 않는 것은 모두 404페이지가 뜬다.
- true라면 getStaticPaths로 리턴되지 않는 것은 404로 뜨지 않고, fallback페이지가 뜨게된다.
if(router.isFallback){
return <div>Loading...</div>
}
import React, { useState } from 'react';
const MyPage = ({ data }) => {
const [name, setName] = useState('');
if (data) {
name = data.name;
}
return (
<div>
<h1>My Page</h1>
<p>Name: {name}</p>
</div>
);
};
// getStaticPaths 함수를 사용하여 데이터를 가져옵니다.
// build time에 call됨
export const getStaticPaths = async () => {
const response = await fetch('https://api.example.com/paths');
const data = await response.json();
return {
paths: data.paths.map((path) => ({
pathname: path.pathname,
component: MyPage,
})),
};
};
export default MyPage;
getServerSideProps
- getServerSideProps 함수를 async로 export하면, Next는 각 요청마다 리턴되는 데이터를 getServerSideProps로 pre-render한다.
getServerSideProps를 사용해야 할 때
요청할 때 데이터를 가져와야하는 페이지를 미리 렌더해야 할 때 사용한다. 서버가 모든 요청에 대한 결과를 계산하고, 추가 구성없이 CDN에 의해 결과를 캐시할 수 없기때문에 첫번째 바이틔까지의 시간은 getStaticProps 보다 느리다.
import React from 'react';
export async function getServerSideProps(context) {
// Fetch data from an API or database
const res = await fetch('https://api.example.com/posts');
const posts = await res.json();
return {
props: {
posts,
},
};
}
export default function Posts({ posts }) {
return (
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
);
}
useQuery
useQuery 훅을 사용하여 클라이언트에서 데이터를 가져오면 페이지가 요청될 때마다 데이터를 가져온다. 따라서, 페이지가 처음 요청될 때는 데이터를 가져오는 데 시간이 걸릴 수 있다.
useQuery 훅은 다음과 같은 파라미터를 사용한다.
- query: 데이터를 가져올 URL
- options: 데이터 가져오기 옵션
- callback: 데이터 가져오기 완료 후 실행되는 콜백 함수
import React, { useState } from 'react';
const MyPage = () => {
const [name, setName] = useState('');
// useQuery 훅을 사용하여 데이터를 가져옵니다.
const { data, loading, error } = useQuery('https://api.example.com/data');
if (loading) {
return <div>Loading...</div>;
} else if (error) {
return <div>Error: {error.message}</div>;
}
if (data) {
name = data.name;
}
return (
<div>
<h1>My Page</h1>
<p>Name: {name}</p>
</div>
);
'Frontend > Next.js' 카테고리의 다른 글
Nextjs 프로젝트 git pull/clone 받고 실행 오류 (0) | 2024.02.02 |
---|---|
[Next.js] 중고마켓 앱2 (1) | 2024.02.01 |
[Next.js] 중고마켓 앱1 (0) | 2024.02.01 |
[Next.js] pocketbase로 Create, Read..하는 튜토리얼2 (13버전 이후) (0) | 2024.01.17 |
[Next.js] 튜토리얼 블로그 (0) | 2024.01.17 |