> 웹 프론트엔드 > JS 튜토리얼 > Next.js: 가장 인기 있는 React 프레임워크에 대한 확실한 가이드

Next.js: 가장 인기 있는 React 프레임워크에 대한 확실한 가이드

Mary-Kate Olsen
풀어 주다: 2024-12-07 08:27:14
원래의
394명이 탐색했습니다.

Next.js: La Guía Definitiva del Framework React más Popular

Next.js는 최신 웹 애플리케이션 구축을 위한 가장 인기 있는 React 프레임워크가 되었습니다. 서버 측 렌더링(SSR), 정적 생성 및 뛰어난 개발 경험에 중점을 둔 Next.js는 확장 가능한 고성능 웹 애플리케이션을 구축하는 데 필요한 모든 것을 제공합니다.

왜 Next.js인가?

주요 특징

  1. 하이브리드 렌더링

    • 서버측 렌더링(SSR)
    • 정적 사이트 생성(SSG)
    • 클라이언트측 렌더링(CSR)
    • 증분형 정적 재생(ISR)
  2. 자동 최적화

    • 이미지 최적화
    • 글꼴 최적화
    • 스크립트 최적화
    • 제로 구성
  3. 개발자 경험

    • 빠른 새로고침
    • 타입스크립트 지원
    • 파일 시스템 라우팅
    • API 경로

첫 번째 단계

프로젝트 만들기

npx create-next-app@latest mi-proyecto
cd mi-proyecto
npm run dev
로그인 후 복사

프로젝트 구조

├── app/
│   ├── layout.tsx
│   ├── page.tsx
│   └── globals.css
├── public/
│   └── images/
├── components/
│   └── ui/
├── lib/
├── next.config.js
└── package.json
로그인 후 복사

Next.js 14의 라우팅

기본 페이지

// app/page.tsx
export default function Home() {
  return (
    <main>
      <h1>Bienvenidos a Next.js</h1>
    </main>
  );
}
로그인 후 복사

동적 경로

// app/blog/[slug]/page.tsx
export default function BlogPost({ params }: { params: { slug: string } }) {
  return (
    <article>
      <h1>Post: {params.slug}</h1>
    </article>
  );
}
로그인 후 복사

공유 레이아웃

// app/layout.tsx
import { Inter } from 'next/font/google';
const inter = Inter({ subsets: ['latin'] });

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body className={inter.className}>
        <nav>
          {/* Navegación común */}
        </nav>
        {children}
      </body>
    </html>
  );
}
로그인 후 복사

데이터 가져오기

서버 구성 요소

// app/posts/page.tsx
async function getPosts() {
  const res = await fetch('https://api.ejemplo.com/posts', {
    next: { revalidate: 3600 } // Revalidar cada hora
  });
  return res.json();
}

export default async function Posts() {
  const posts = await getPosts();

  return (
    <div>
      {posts.map(post => (
        <article key={post.id}>
          <h2>{post.title}</h2>
          <p>{post.excerpt}</p>
        </article>
      ))}
    </div>
  );
}
로그인 후 복사

정적 생성

// app/posts/[id]/page.tsx
export async function generateStaticParams() {
  const posts = await getPosts();

  return posts.map((post) => ({
    id: post.id.toString(),
  }));
}

export default async function Post({ params }: { params: { id: string } }) {
  const post = await getPost(params.id);

  return (
    <article>
      <h1>{post.title}</h1>
      <div>{post.content}</div>
    </article>
  );
}
로그인 후 복사

API 경로

// app/api/posts/route.ts
import { NextResponse } from 'next/server';

export async function GET() {
  try {
    const posts = await getPosts();
    return NextResponse.json(posts);
  } catch (error) {
    return NextResponse.json(
      { error: 'Error al obtener posts' },
      { status: 500 }
    );
  }
}

export async function POST(request: Request) {
  try {
    const data = await request.json();
    const newPost = await createPost(data);
    return NextResponse.json(newPost, { status: 201 });
  } catch (error) {
    return NextResponse.json(
      { error: 'Error al crear post' },
      { status: 500 }
    );
  }
}
로그인 후 복사

최적화

이미지

import Image from 'next/image';

export default function Profile() {
  return (
    <Image
      src="/perfil.jpg"
      alt="Foto de perfil"
      width={500}
      height={300}
      priority
    />
  );
}
로그인 후 복사

글꼴

import { Roboto } from 'next/font/google';

const roboto = Roboto({
  weight: ['400', '700'],
  subsets: ['latin'],
  display: 'swap',
});

export default function Layout({ children }) {
  return (
    <div className={roboto.className}>
      {children}
    </div>
  );
}
로그인 후 복사

상태 관리

클라이언트 구성요소

'use client';

import { useState } from 'react';

export default function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Contador: {count}</p>
      <button onClick={() => setCount(count + 1)}>
        Incrementar
      </button>
    </div>
  );
}
로그인 후 복사

양식화

CSS 모듈

// components/Button.tsx
import styles from './Button.module.css';

export default function Button({ children }) {
  return (
    <button className={styles.button}>
      {children}
    </button>
  );
}
로그인 후 복사

순풍 CSS

export default function Card({ title, content }) {
  return (
    <div className="p-6 max-w-sm mx-auto bg-white rounded-xl shadow-lg flex items-center space-x-4">
      <div>
        <div className="text-xl font-medium text-black">{title}</div>
        <p className="text-gray-500">{content}</p>
      </div>
    </div>
  );
}
로그인 후 복사

미들웨어

// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
  // Verificar autenticación
  const token = request.cookies.get('token');

  if (!token) {
    return NextResponse.redirect(new URL('/login', request.url));
  }

  return NextResponse.next();
}

export const config = {
  matcher: '/dashboard/:path*',
};
로그인 후 복사

테스트

// __tests__/Home.test.tsx
import { render, screen } from '@testing-library/react';
import Home from '@/app/page';

describe('Home', () => {
  it('renders a heading', () => {
    render(<Home />);
    const heading = screen.getByRole('heading', { level: 1 });
    expect(heading).toBeInTheDocument();
  });
});
로그인 후 복사

전개

생산 구성

// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  images: {
    domains: ['tu-dominio.com'],
  },
  async redirects() {
    return [
      {
        source: '/old-page',
        destination: '/new-page',
        permanent: true,
      },
    ];
  },
};

module.exports = nextConfig;
로그인 후 복사

모범 사례

  1. 코드 구성
   app/
   ├── (auth)/
   │   ├── login/
   │   └── register/
   ├── (dashboard)/
   │   ├── profile/
   │   └── settings/
   └── (marketing)/
       ├── about/
       └── contact/
로그인 후 복사
  1. 오류 처리
   // app/error.tsx
   'use client';

   export default function Error({
     error,
     reset,
   }: {
     error: Error & { digest?: string };
     reset: () => void;
   }) {
     return (
       <div>
         <h2>¡Algo salió mal!</h2>
         <button onClick={() => reset()}>Intentar de nuevo</button>
       </div>
     );
   }
로그인 후 복사
  1. 로드 상태
   // app/loading.tsx
   export default function Loading() {
     return (
       <div className="flex items-center justify-center">
         <div className="animate-spin rounded-full h-32 w-32 border-b-2 border-gray-900" />
       </div>
     );
   }
로그인 후 복사

결론

Next.js 14 제공:

  • 뛰어난 성능
  • 뛰어난 DX(개발자 경험)
  • 확장성
  • 렌더링 유연성
  • React와의 원활한 통합

다음과 같은 경우에 이상적인 선택입니다.

  • 비즈니스 웹 애플리케이션
  • 전자상거래 사이트
  • SaaS 애플리케이션
  • 동적 콘텐츠 사이트

추가 리소스

  • 공식 문서
  • Next.js 예시
  • Next.js 알아보기
  • 버셀 블로그

프로젝트에서 Next.js를 사용하고 있나요? 어떤 기능이 가장 유용하다고 생각하시나요? 댓글로 여러분의 경험을 공유해주세요! ?

nextjs #반응 #webdev #javascript

위 내용은 Next.js: 가장 인기 있는 React 프레임워크에 대한 확실한 가이드의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:dev.to
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿