ホームページ >ウェブフロントエンド >jsチュートリアル >Next.js: 最も人気のある React フレームワークの決定版ガイド

Next.js: 最も人気のある React フレームワークの決定版ガイド

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2024-12-07 08:27:14366ブラウズ

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

Next.js は、最新の Web アプリケーションを構築するための最も人気のある React フレームワークになりました。 Next.js は、サーバーサイド レンダリング (SSR)、静的生成、優れた開発エクスペリエンスに重点を置いており、高性能でスケーラブルな Web アプリケーションを構築するために必要なものをすべて提供します。

なぜ Next.js なのか?

主な特長

  1. ハイブリッド レンダリング

    • サーバーサイド レンダリング (SSR)
    • 静的サイト生成 (SSG)
    • クライアントサイド レンダリング (CSR)
    • 増分静的再生 (ISR)
  2. 自動最適化

    • 画像の最適化
    • フォントの最適化
    • スクリプトの最適化
    • 設定ゼロ
  3. 開発者エクスペリエンス

    • 高速更新
    • TypeScript のサポート
    • ファイルシステムのルーティング
    • 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 とのシームレスな統合

次のような場合に最適です。

  • ビジネス Web アプリケーション
  • 電子商取引サイト
  • SaaS アプリケーション
  • 動的コンテンツ サイト

追加リソース

  • 公式ドキュメント
  • Next.js の例
  • Next.js を学ぶ
  • Vercel ブログ

プロジェクトで Next.js を使用していますか?どの機能が最も便利だと思いますか?コメントであなたの経験を共有してください! ?

nextjs #react #webdev #javascript

以上がNext.js: 最も人気のある React フレームワークの決定版ガイドの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。