Nextjs13의 app [Nextjs]

김대운·2023년 4월 14일
0

Nextjs

목록 보기
2/4
post-thumbnail

app폴더

next js13 이후부터 pages 폴더를 대체할 app 폴더가 나왔습니다.

아직 베타버전이기 때문에 app폴더를 사용하기 위해서는 next.config.js에서 설정을 해줘야합니다.

/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    appDir: true,
  },
}

module.exports = nextConfig

위 코드를 추가해주시면 됩니다.

이제부터 app폴더의 장점에 대해서 알아보겠습니다.

1. 전역 레이아웃 관리

app 폴더에서는 모든 페이지에서 공통으로 사용되는 레이아웃을 정의할 수 있습니다. 예를 들어, 모든 페이지에서 공통으로 사용되는 네비게이션 바, 푸터, 헤더 등의 컴포넌트를 app 폴더 내의 layout.tsx 파일에서 정의 할 수 있습니다.

/app/layout.tsx
import { Nunito } from 'next/font/google'

import Navbar from './components/navbar/Navbar'
import LoginModal from '@/app/components/modals/LoginModal'
import RegisterModal from '@/app/components/modals/RegisterModal'
import SearchModal from '@/app/components/modals/SearchModal'
import ClientOnly from './components/ClientOnly'

import './globals.css'
import ToasterProvider from './providers/ToasterProvider'
import getCurrentUser from './actions/getCurrentUser'
import RentModal from './components/modals/RentModal'

export const metadata = {
  title: 'airbnb-clone',
  description: 'Generated by create airbnb wep with next',
}

const font = Nunito({
  subsets: ['latin'],
})

export default async function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  const currentUser = await getCurrentUser()

  return (
    <html lang="en">
      <body className={font.className}>
        <ClientOnly>
          <ToasterProvider />
          <LoginModal />
          <RegisterModal />
          <RentModal />
          <SearchModal />
          <Navbar currentUser={currentUser} />
        </ClientOnly>
        <div className="pb-20 pt-28">{children}</div>
      </body>
    </html>
  )
}

위 코드처럼 전역에서 처리되는 토스트 메세지, 로그인 회원가입 모달, 검색 모달, 네브바 등 다양한 컴포넌트를 공통으로 사용할 수 있습니다.

레이아웃 시스템의 장점은 다음과 같습니다.

  1. 중복 코드 제거: 기존의 페이지 구성에서 공통적으로 사용되는 코드를 중복해서 작성해야하는 문제를 해결할 수 있습니다. Layout 컴포넌트를 사용하면 공통 레이아웃을 담당하는 컴포넌트를 따로 분리하여 코드 중복을 제거할 수 있습니다.

  2. 유지보수 용이성: 레이아웃이 변경되는 경우 모든 페이지에서 해당 레이아웃을 변경해야하는 번거로움이 줄어듭니다. Layout 컴포넌트만 수정하면 모든 페이지에 적용이 가능하기 때문입니다.

  3. Nested Layout이라는 새로운 라우팅 방식을 지원합니다.

Nested Layout은 여러 컴포넌트가 중첩된 형태로 렌더링되는 경우, 각각의 컴포넌트에 대해 다른 레이아웃을 적용할 수 있도록 합니다.
이를 통해 웹 사이트나 앱의 전반적인 디자인 및 사용자 경험을 조정하고 개선할 수 있습니다.

예를 들어, 회사 웹 사이트의 경우, 전체적인 레이아웃은 동일하지만, 각각의 페이지에 따라 다른 레이아웃을 적용할 수 있습니다. Nested Layout을 사용하면 이러한 기능을 쉽게 구현할 수 있습니다.

Nested Layout은 pages 폴더 내에서 생성된 페이지에서 app 폴더 내에서 생성된 레이아웃 컴포넌트로 중첩됩니다. 중첩된 레이아웃은 상위 레이아웃에 대한 참조를 포함하고 있으며, 이를 통해 상위 레이아웃의 스타일 및 기능을 덮어쓰거나 상속할 수 있습니다.

  1. 코드 가독성 향상: 페이지 내에서 레이아웃을 직접 작성하는 것보다, Layout 컴포넌트를 사용하여 코드를 구조화하면 가독성이 향상됩니다.

  2. 성능 개선: 페이지를 미리 렌더링해두면 브라우저에서 페이지 로딩 시간을 줄일 수 있습니다. 또한, Layout 컴포넌트를 사용하여 중복 코드를 제거하면 번들 크기가 줄어들어 페이지 로딩 속도가 개선될 수 있습니다.

2. 전역 에러 처리

app/error.tsx  
'use client';

import { useEffect } from "react";

import EmptyState from "@/app/components/EmptyState";

interface ErrorStateProps {
  error: Error
}

const ErrorState: React.FC<ErrorStateProps> = ({ error }) => {
  useEffect(() => {
    console.error(error);
  }, [error]);

  return ( 
    <EmptyState
      title="Uh Oh"
      subtitle="Something went wrong!"
    />
   );
}
 
export default ErrorState;

app 폴더에서는 전역 에러 핸들러를 구현하여, 애플리케이션 전역에서 발생하는 예외를 처리할 수 있습니다.
정말 간편하게 전역 예외 처리를 할 수 있게 되었습니다.

3. API 라우트 관리

app 폴더 내의 api 폴더에서는 API 라우트를 구현할 수 있습니다. 이전 버전에서는 pages/api 폴더에 API 라우트를 작성해야 했으나, Next.js 13에서는 app/api 폴더에서 API 라우트를 작성할 수 있습니다.

/app/api/register/route.ts 
import { NextResponse } from 'next/server'
import bcrypt from 'bcrypt'

import prisma from '@/app/libs/prismadb'

export async function POST(request: Request) {
  const body = await request.json()
  const { email, name, password } = body

  const hashedPassword = await bcrypt.hash(password, 12)

  const user = await prisma.user.create({
    data: {
      email,
      name,
      hashedPassword,
    },
  })

  return NextResponse.json(user)
}

Next.js에서 제공하는 API Routes 기능을 사용하여 작성된 코드입니다.

API Routes 기능은 다음과 같은 장점을 가지고 있습니다.

  1. 쉬운 구성 및 관리: Next.js의 API Routes를 사용하면 API 서버를 쉽게 구성할 수 있습니다. 기존의 Node.js API 서버와 달리, Next.js에서 API를 작성하면 필요한 파일들만 작성하면 됩니다. 따라서 코드의 구성이 단순화되고, 유지 보수 및 관리도 쉬워집니다.

  2. Serverless 지원: API Routes를 사용하면 API 서버를 Serverless로 배포할 수 있습니다. 이를 통해 서버 인프라 관리에 대한 부담을 줄이고, 더욱 확장성 높은 서비스를 구성할 수 있습니다.

  3. 빠른 응답 속도: Next.js의 API Routes는 서버사이드 렌더링 방식을 사용하므로, 빠른 응답 속도를 보장합니다. 이를 통해 사용자 경험을 개선할 수 있습니다.

  4. TypeScript 지원: Next.js의 API Routes는 TypeScript를 지원합니다. 따라서 타입 안정성을 보장하며 코드의 가독성을 높일 수 있습니다.

  5. 강력한 유효성 검사: Next.js의 API Routes는 내장된 유효성 검사 라이브러리를 사용할 수 있습니다. 이를 통해 API 요청에 대한 유효성을 검사하고, 보안성을 높일 수 있습니다.

/app/components/modals/RegisterModal.tsx
'use client'

import axios from 'axios'
... 

const RegisterModal = () => {
  const registerModal = useRegisterModal()
...

  const onSubmit: SubmitHandler<FieldValues> = (data) => {
    setIsLoading(true)

    axios
      .post('/api/register', data)
      .then(() => {
        toast.success('Registered!')
        registerModal.onClose()
        loginModal.onOpen()
      })
      .catch((error) => {
        toast.error(error)
      })
      .finally(() => {
        setIsLoading(false)
      })
  }

 ...
}
export default RegisterModal

위 코드와 같이 axios로 바로 post 요청이 가능 합니다.
server와 client를 한번에 관리할 수 있다는 점이 정말 편리하다고 생각했습니다.

4. Loading UI

Next.js 13은 React Suspense 와 함께하는 의미있는 로딩 UI를 만들 수 있도록 loading.js라는 새로운 파일 협약을 소개했습니다.

loading UI는 컨텐츠가 서버로부터 로드 되는동안 즉시 loading 상태를 보여줄 수 있으며, 새로운 콘텐츠는 렌더링이 끝나면 자동으로 교체됩니다.

또 새로운 컨텐츠만 새로 렌더링 되므로 새로 렌더링 되는 영역에만 loading UI가 표시됩니다.

/app/loading.tsx
import Loader from "@/app/components/Loader";

const Loading = () => {
  return ( 
    <Loader />
   );
}
 
export default Loading;

이렇게 간단한 코드로 loading UI를 만들 수 있습니다 !

0개의 댓글