(리액트는 라이브러리, Next.js는 프레임워크이다. )
React의 SSR(Server Side Rendering)을 쉽게 구현할 수 있게 도와주는 간단한 프레임워크이다. 리액트로 개발할때 SPA을 이용하며 CSR(Client Side Rendering)을 하기때문에 좋은점도 있지만 단점도 있다. 검색엔진최적화(SEO)에 취약하다는 것이다. CSR을 하면 첫페이지에서 빈 html을 가져와서 JS파일을 해석하여 화면을 구성하기때문에 포털검색에 거의 논출될 일이 없다.(크롤링 안됨)
하지만 Next.js에서는 Pre-Rendering을 통해서 페이지를 미리 렌더링하며 완성된 HTML을 가져오기 때문에 사용자와 검색엔진 크롤러에게 바로 렌더링된 페이지를 전달 할 수 있게 된다.
리액트에서도 SSR를 지원하지만 구현하기에 굉장히 복잡하기 때문에 Next.js를 통해서 이문제를 해결할 수 있다.
npx create-next-app@latest
yarn create next-app
npx create-next-app ./ --typescript
타입스크립트 템플릿 사용
index.ts
가 처음 "/" 페이지_app.tsx
는 공통되는 레이아웃을 작성함. 모든 페이지에 공통으로 들어가는 걸 넣어주려면 여기에 넣는다. url을 통해 특정 페이지에 진입하기 전 통과하는 인터셉터 페이지다. 모든 페이지를 pre-render한다.
pre-render 테스트 하는방법
자바스크립트 Disable 자바스크립트 disable 방법
Ctrl+Shift+P
를 눌러 javascript검색후 disable명령어 실행(클릭)
주소표시줄에 다음 마크와 Sources패널에 javascript is disabled라고 뜨는지 확인한다.
보통 React사이트 들어가기
테스트용 리액트 기본 사이트
Next.js 사이트 들어가기
테스트용 NextJS 기본 사이트
NextJS에서 데이터를 가져오는 방법은 여러가지가 있다.
보통 리액트에서 데이터를 가져올때 useEffect안에서 가져온다. 하지만 Nextjs에서는 다른방법을 사용해서 가져온다.
pages/post/[id].js
)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를 사용해야할 때
getStaticPaths 함수는 페이지의 리퀘스트 경로와 함께 데이터의 경로를 정의한다. 따라서, 페이지별로 다른 데이터를 가져오거나, 데이터를 캐싱할 수 있습다.
어떠한 경로가 pre-render될 지 결정한다.
만약 pages/posts/[id].js
라는 이름의 동적 라우팅을 사용하는 페이지가 있다면 아래와 같이 된다.
return {
paths: [
{ params: {id: '1'} },
{ params: {id: '2'} },
],
fallback: ...
}
pages/posts/[postId]/[commentId]
라면, params는 postId와 commentIdpages/[...slug]
와 같이 모든 경로를 사용한다면, params는 slug가 담긴 배열이어야한다. ['postId', 'commentId']
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를 사용해야 할 때
요청할 때 데이터를 가져와야하는 페이지를 미리 렌더해야 할 때 사용한다. 서버가 모든 요청에 대한 결과를 계산하고, 추가 구성없이 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 훅은 다음과 같은 파라미터를 사용한다.
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>
);