Next JS 기초 개념 정리
Intro
- 본 내용은 강의 제공 사이트 유데미 Laith Harb 강사님의 "The Next.js 13 Bootcamp - The Complete Developer Guide" 강의를 듣고 정리하였습니다.
- https://www.udemy.com/course/the-nextjs-13-bootcamp-the-complete-developer-guide/
Intro
- 현재 블로그 또한
Next.js
를 이용해 만들어졌지만 만든 시점은12
버전이었다. 당시 사전 지식 없이 무작정 만들다보니 부족한 부분이 보였고 블로그 업데이트가 필요하다고 느꼈다. 이 기회를 빌려Next.js
에 대해 알아보도록 해야겠다. - Next beta Docs를 참조하시면 더욱 도움이 됩니다.
I 준비사항
아래와 같은 환경이 구성되어있어야 합니다.
- Node.js 16.8 이상의 버전
I-I 프로젝트 설정하기
프로젝트는 다음과 같이 구성하겠습니다. npx의 경우 node 설치 시 기본적으로 같이 설치가 진행됩니다.
> npx create-next-app@13.1.1 --experimental-app
Need to install the following packages:
create-next-app@13.1.1
Ok to proceed? (y) y
✔ What is your project named? … opentablenextjs
✔ Would you like to use TypeScript with this project? … No / Yes
✔ Would you like to use ESLint with this project? … No / Yes
Creating a new Next.js app in /Users/wooglim/dev/nextPractice/opentablenextjs.
또한 Typescript를 기본 언어로 사용하겠습니다.
프로젝트 구성 완료 시 package.json
을 보시면 다음과 같이 script
가 작성되어 있습니다. 일단 npm run dev
명령을 입력해 서버를 실행해 봅시다.
// package.json
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
}
npm run dev
입력
> npm run dev
브라우저에서 접속하면 다음과 같은 페이지가 보입니다. 해당 루트 페이지의 경로는 /app/page.tsx
입니다.
위 app
폴더 부분에서 가장 많은 작업이 일어날 것입니다. global.css
및 레이아웃을 주로 구성할테니 말이죠.
I-II 유용한 CSS 라이브러리 설치하기
페이지 작업 시 CSS를 직접 작성하는건 매우 어렵습니다.. 제 기준에서는요, 그래서 tailwindcss
를 이용하겠습니다.
설치는 공식문서와 같이 진행합니다. 버전은 알아보신 후 명시하시길 권장드립니다. 우선dev
종속성을 갖도록 설정하겠습니다.
> npm install -D tailwindcss@3.2.4 postcss@8.4.20 autoprefixer@10.4.13
다음으로 초기화가 필요합니다. 이후 폴더를 보시면 tailwind.config.js
, postcss.config.js
가 추가될겁니다.
> npx tailwindcss init -p
이후 tailwind.config.js
에 다음과 같이 설정해줍니다. app
폴더내 모든 디렉토리에 포함된 js,ts,jsx,tsx
파일은 tailwindcss
를 사용할 수 있게됩니다.
// tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
// tailwind CSS 를 적용할 경로를 app폴더내 모든 디렉토리내 js,ts,jsx,tsx파일에 적용
content: ["./app/**/*.{js,ts,jsx,tsx}"],
theme: {
extend: {},
},
plugins: [],
}
추가로 app/global.css
파일 루트에 다음과 같이 Tailwind의 레이어에 대한 지시문을 파일에 추가합니다.
@tailwind base;
@tailwind components;
@tailwind utilities;
여기까지입니다. 이제 app 폴더내 js,ts,jsx,tsx
파일에서 tailwindCSS
를 온전히 사용할 수 있게됩니다. 다음과 같이 공식문서를 보시면 적용할 수 있는 스타일을 조회할 수 있습니다.
폰트 크기도 달라지게 되므로 다음과 같이 tailwind.config.js
에 폰트 사이즈를 지정할 수 있습니다. 이후 사용 시 태그 className
(눈치채셨겠지만 React를 따릅니다.) 속성에 text-설정명
과 같이 적용할 수 있습니다.
// tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
// tailwind CSS 를 적용할 경로를 app폴더내 모든 디렉토리내 js,ts,jsx,tsx파일에 적용
content: ["./app/**/*.{js,ts,jsx,tsx}"],
theme: {
extend: {},
fontSize: {
"2xsm": "10px",
xsm: "12px",
sm: "13px",
reg: "15px",
lg: "18px",
"2xl": "22px",
"3xl": "25px",
"4xl": "32px",
"5xl": "40px",
"6xl": "50px",
"7xl": "70px"
}
},
plugins: [],
}
I-III 파일 기반 라우팅
Next JS는 파일 기반 라우팅을 따릅니다. 그리고 루트 페이지인 App/page.tsx
경로는 도메인을 입력하면 렌더링 됩니다. 만일 locahost:3000/search
와 같은 경로를 찾는다면 다음과 같은 폴더 트리 구조를 형성해야합니다.
> APP[Folder]
page.tsx
> search[Folder]
page.tsx
> restaurant[Folder]
> shakeshack[Folder]
page.tsx
localhost:3000
을 요청하면 App/page.tsx
를 렌더링 하고 localhost:3000/search
를 요청하면App/search/page.tsx
를 렌더링합니다.
간단히 라우팅이 가능하지만 단점으로는 변경할 수 없습니다. 만일 동적인 라우팅이 가능하도록 하고 싶다면 아래와 같이 []
로 묶어 경로를 설정합니다.
> APP[Folder]
page.tsx
> search[Folder]
page.tsx
> restaurant[Folder]
> [name][Folder]
page.tsx
혹은 아래와 같이 slug
를 설정하는 것이 대표적입니다. 찾는 경로에 따라 해당 디렉토리 경로로 이동하는 것이죠.
> APP[Folder]
page.tsx
> search[Folder]
page.tsx
> restaurant[Folder]
> [slug][Folder]
page.tsx
I-IV 링크 구성 하기
HTML의 a태그와 같이 Link
태그로 링크를 연결할 수 있습니다. 특정 버튼을 누르면 파일 기반 라우팅을 이용해 홈으로 이동할 수 있고, 타 메뉴 이동이 가능하죠.
다음 코드와 같다면 localhost:port
즉 홈 경로로 이동할 것입니다.
import Link from "next/link"
<Link href="/" className="font-bold text-gray-700 text-2xl">
Home
</Link>
Link
태그는 a
태그를 제외한 태그를 감쌀 수 있습니다. a
태그의 스타일은 적용하지 않습니다. 어떠한 경로에 있는 파일(menu/page.tsx
) 여도, Link
태그의 시작지점은 초기 도메인(루트 프로젝트 경로)입니다. 때문에 menu/page.tsx
페이지에서 restaurant/[slug]/page.tsx
를 탐색하고 싶다면 Link
태그 href
속성으로 /restaurant/동적인 값
만 입력해주면 됩니다.
I-V Hook 맛보기
먼저 훅을 대부분 클라이언트에서 작동하므로 page.tsx
상단에 서버 구성 요소를 클라이언트 요소로 바꾸기 위해 "use client"
를 입력해줍니다.
// page.tsx
"use client"
import Image from 'next/image'
import { Inter } from '@next/font/google'
import styles from './page.module.css'
import Link from 'next/link'
import {useRouter} from "next/navigation"
import { useState } from 'react'
const inter = Inter({ subsets: ['latin'] })
export default function Home() {
const router = useRouter();
const [location, setLocation] = useState("");
이후에는 useRouter, userState
등 클라이언트에서 온전히 사용할 수 있게됩니다.
두개의 훅을 사용해 다음과 같이 검색을 구현할 수 있습니다. 버튼을 클릭하면 search
구문이 url에 붙게됩니다.
<div className="text-left text-lg py-3 m-auto flex justify-center">
<input
className="rounded mr-3 p-2 w-[450px]"
type="text"
placeholder="State, city or town"
value={location}
onChange={(e) => setLocation(e.target.value)}
/>
<button className="rounded bg-red-600 px-9 py-2 text-white" onClick={() => {
if(location === "banana") return;
router.push("/search");
}}>
Let's go
</button>
</div>