Next.js는 React의 SSR을 간단하게 구현하기위해서 사용하는 React프레임워크이다.
난 그동안 create-react-app을 사용하여 REACT를 사용해왔다. 그러나 CRA로 만든 서비스는 SEO에 굉장히 좋지않다. 즉 index.html파일안이 div태그 하나로만 이루어져있기에 크롤링시 빈페이지를 크롤링하게 되는것이다. 그러나 Nextjs로 만든 서비스는 모든 태그를 포함하고 있다.
CRA를 사용하여 만든 서비스는 CSR으로 구현되기 때문에 처음 렌더링시 SSR에 비해 다소 시간이 오래 걸린다. 물론 처음 렌더링 이후에는 SSR보다 빠른 속도를 보여주지만 처음 렌더링시 사용자가 보이는 화면이 늦게 나온다는 단점이있다.
Nextjs를 사용하면 ssr과 csr을 같이 사용하여 처음에도 사용자가 빠른 화면을 볼수있도록 도와준다.
//터미널에 다음과 같이 작성하여 nextjs를 설치한다.
npx create-next-app
처음 설치하고나면 다음과 같이 폴더트리가 생성된다.
1. pages폴더에는 _app.js와 index.js가 만들어져있다.
2. pages폴더안에 about.js파일을 만든다.
// pages/about,js
const about = () => {
return (
<div>
<p>about</p>
</div>
);
};
export default about;
// components/Layout.js
import style from "../styles/Layout.module.css";
const Layout = ({ children }) => {
return (
<div>
<div className={style.container}>
<main className={style.main}>{children}</main>
</div>
</div>
);
};
export default Layout;
// pages/_app.js
import "../styles/globals.css";
import Layout from "../components/Layout";
function MyApp({ Component, pageProps }) {
return (
<Layout>
<Component {...pageProps} />
</Layout>
);
}
export default MyApp;
이제 브라우저로 확인해보면 레이아웃이 잡힌것을 알수있다.
여기서 중요한점은 _app.js는 모든 파일의 기준이 되며, css모듈을 사용하기위해서는 파일이름을 이름.module.css로 만들어야 한다는 것이다.
// components/Nav.js
import Link from "next/link";
import navStyles from "../styles/Nav.module.css";
const Nav = () => {
return (
<nav className={navStyles.nav}>
<ul>
<li>
<Link href='/'>Home</Link>
</li>
<li>
<Link href='/about'>About</Link>
</li>
</ul>
</nav>
);
};
export default Nav;
Link는 클릭시 바로 라우팅해주는 a태그 기능을 가지고있다.react-router-dom의 Link와 같은 개념이며 to대신 href로 경로를 설정할 수 있다.
// components/Layout.js
import style from "../styles/Layout.module.css";
import Nav from "./Nav";
const Layout = ({ children }) => {
return (
<>
<Nav />
<div>
<div className={style.container}>
<main className={style.main}>{children}</main>
</div>
</div>
</>
);
};
export default Layout;
레이아웃으로 적용했던 태그들 상단에 Nav를 적용함으로써 레이아웃과 상관없는 스타일을 가질수 있다.
// pages/index.js
import Head from "next/head";
import ArticleList from "../components/ArticleList";
export default function Home({ articles }) {
console.log(articles)
return (
<div>
<Head>
<title>news</title>
<meta name='keywords' content='programming' />
</Head>
</div>
);
}
export const getStaticProps = async () => {
const res = await fetch(
"https://jsonplaceholder.typicode.com/posts?_limit=6"
);
const articles = await res.json();
return {
props: {
articles,
},
};
};
// (6) [{…}, {…}, {…}, {…}, {…}, {…}]
getStaticProps의 return으로 넘긴 {props:{articles}}는 Home컴포넌트의 props로 들어오게된다.
// components/ArticleList.js
import articleStyles from "../styles/Article.module.css";
import ArticleItem from "./ArticleItem";
const ArticleList = ({ articles }) => {
return (
<div className={articleStyles.grid}>
{articles.map((article) => (
<ArticleItem article={article} />
))}
</div>
);
};
export default ArticleList;
// components/ArticleItem.js
import articleStyles from "../styles/Article.module.css";
import Link from "next/link";
const ArticleItem = ({ article }) => {
return (
<Link href='/article/[id]' as={`/article/${article.id}`}>
<a className={articleStyles.card}>
<h3>{article.title} →</h3>
<p>{article.body}</p>
</a>
</Link>
);
};
export default ArticleItem;
1.Link태그로 클릭시 넘어갈 태그를 감싸준다.
2.href 속성을 사용하여 주소를 적는다
3.href='/article/[id]' 대괄호로 감싸진 주소는 usePrams와 같은 기능을 한다.
4. as속성을 넣어 id를 넣어준다. as={'/article/${article.id}'
}
이제 화면에 구현된 Link를 클릭하면 404페이지가 나올것이다.
경로에 맞는 파일을 만들지 않았기 때문이다.
1.pages -> article -> [id] -> index.js
// pages/article/[id]/index.js
const article = () => {
return <div>아티클</div>;
};
export default article;
이제 클릭시 화면이 넘어가는게 보여질 것이다.
폴더이름을 다이나믹라우트의 적용한 대괄호와 똑같이 네이밍 함으로써 이동될 페이지를 만들수 있다.
// pages/article/[id]/index.js
import { useRouter } from "next/router";
const article = () => {
const router = useRouter();
const { id } = router.query;
return <div>아티클{id}</div>;
};
export default article;
useParams를 사용하여 id값을 가져올수 있다.