React 를 기반으로하는 웹 개발 프레임워크
React 는 UI를 만들기위한 자바스크립트 라이브러리이며, React 로 작성된 애플리케이션은 SPA(Single Page Application) 이라고 부름// Nextjs 설치 npx create-next-app@latest
React 라이브러리
라이브러리는 알아서 사람이 작업하면 됨
재료만 제공해주고 개발자가 온전히 본인이 만드는것
자유도가 높음
규칙이 없음
직접 재료를 사서 요리하는것
react => 라이브러리
Nextjs 프레임워크
프레임워크가 개발자가 만들어놓은 코드 사용하는것
특정한 규칙들을 다 정해놓음
밀키트를 사서 요리 하는것
nextjs => 프레임워크
제일 큰 차이는 규칙
사용법
import { 글꼴명 } from "next/font/google"; // 문법
import { Nanum_Pen_Script } from "next/font/google"; // 예제
예시
import { Nanum_Pen_Script } from "next/font/google";
export const nanum = Nanum_Pen_Script({ weight: "400", subsets: ["latin"] });
import { nanum, notosansKr } from "../../public/fonts/google_fonts";
export default function page() {
return (
<>
<h1 className={`${nanum.className}`}>page</h1>
<h1 className={`${notosansKr.className}`}>page</h1>
</>
);
}
// local에 업로드한 이미지를 Image 컴포넌트로 참조하려면 아래처럼 이미지 파일 import해서 사용해야함 import Image from "next/image"; import dummyImage from "/public/images/dummy-image-1.png"; export default function page() { return ( <> <Image src={dummyImage} alt="이미지" priority={false} /> </> ); }
// 외부 이미지 참조할때, width, height 속성 필요 <Image src={ "https://cdn.pixabay.com/photo/2017/01/03/22/00/tower-1950742_1280.jpg" } alt="이미지" fill priority={true} />
// next.config.mjs /** @type {import('next').NextConfig} */ const nextConfig = { images: { remotePatterns: [ { protocol: "https", hostname: "cdn.pixabay.com", // ex) pixbay사이트 사용하는 사이트 host주소 넣어야함 port: "", }, ], }, }; export default nextConfig;
라우팅
- 라우팅은 사용자가 요청한 URL에 따라 어떤 페이지를 보여줄지를 결정하는 과정
- Next.JS는 앱 라우팅 / 페이지 라우팅을 사용하여 URL 경로와 페이지 파일을 직접 연결
- 예를 들어서 사용자가 ‘/about’ 경로를 입력하면, Next.JS는 해당 경로와 맞는 페이지를 표시합니다.
라우터(Router)
- 라우터는 이러한 라우팅을 관리하고 처리하는 기능을 제공하는 도구
- Next.JS에서는 페이지 라우터는 ‘next/router’, 앱 라우터는 ‘next/navigation’가 라우터 관리 도구
- 일반적으로 라우터는 사용자의 URL을 해석하고 해당 URL에 맞는 컴포넌트를 렌더링함
라우트(Route)
- 라우트는 URL과 특정 컴포넌트 간의 매핑을 나타냄
- 라우트는 일반적으로 페이지의 경로와 해당 경로에 표시할 컴포넌트를 정의하는데 사용됨.
Next.JS 14에서 새롭게 도입된 라우팅 시스템
기본
앱 라우터는 루트에 app 폴더를 생성하면 자동으로 라우트가 생성됨. 예를 들어서 app 폴더 하위에 blog 페이지를 만들고 page.tsx 컴포넌트를 생성하면 /blog에 매핑되는 라우트가 설정됨.
app/ ├── blog/ │ └── page.tsx --- /blog ├── about/ │ └── page.tsx --- /about
다이나믹 경로
app/ └── blog/ ├── page.tsx - /blog └── [id]/ └── page.tsx -- /blog/1 or /blog/2 or /blog/3...
중첩 다이나믹 경로
app/ └── blog/ ├── page.tsx - /blog └── [id]/ ├── page.tsx -- /blog/1 or /blog/2 or /blog/3... └── comment/ └── [reviewId]/ └── page.tsx. -- /blog/2/comment/1
그룹
app (home) page.tsx --- / (auth) login page.tsx --- /login register page.tsx --- /register
Link 컴포넌트
// 리액트와 다르게 to 속성이 아니다 import { Link } from 'next/Link' <Link href="/">Home</Link>
Params
// Nextjs는 기본적으로 params Props 전달받음, 사용하든 안하든 항상 전달 받음 const BlogDetail = (params) => { // /blog/1?lang=ko // { params: { id: '1' }, searchParams: { lang: 'ko' } } console.log(params); return ( <> <h1>BlogDetail Component</h1> </> ); }; export default BlogDetail;
useRouter
// 프로그래밍 방식 라우팅 가능 "use client"; import { useRouter } from "next/navigation"; export default function Home() { const router = useRouter(); console.log(router); return ( <>...</> ); }
push
const router = useRouter(); const useRouterHandler = () => { router.push('/blog'); };
redierct
import { redirect } from "next/navigation"; export default function Product() { redirect("/"); return ( <> <h1>Product Component</h1> </> );
usePathname()
// 현재 라우팅의 경로를 반환하는 훅 "use client"; import { usePathname } from "next/navigation"; export default function Product() { const pathname = usePathname(); console.log(pathname); // http://localhost:3000/products -> /products return ( <> <h1>Product Component</h1> </> ); }
useSearchParams()
// queryString 문자열을 가져올 때 사용하는 훅 "use client"; import { useSearchParams } from "next/navigation"; export default function Product() { const searchParams = useSearchParams(); console.log(searchParams.get("id")); // http://localhost:3000/products?id=1 -> 1 return ( <> <h1>Product Component</h1> </> ); }
Param props
// 페이지 컴포넌트에 기본으로 전달되는 params 옵션 속성을 사용하면 동적 세그먼트 받을 수 있다. type TProps = { params: { id: string; }; searchParams: { lang: string; }; }; export default function ProductDetail(params: TProps) { // http://localhost:3000/products/1 -> {id: 1} console.log(params); //{ params: { id: '1' }, searchParams: { lang: 'ko' } } console.log(params.params.id); // 1 console.log(params.searchParams.lang); // ko return ( <> <h1>ProductDetail Component</h1> </> );