ホームページ >ウェブフロントエンド >jsチュートリアル >Next.js: 最も人気のある React フレームワークの決定版ガイド
Next.js は、最新の Web アプリケーションを構築するための最も人気のある React フレームワークになりました。 Next.js は、サーバーサイド レンダリング (SSR)、静的生成、優れた開発エクスペリエンスに重点を置いており、高性能でスケーラブルな Web アプリケーションを構築するために必要なものをすべて提供します。
ハイブリッド レンダリング
自動最適化
開発者エクスペリエンス
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
// 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 ( <nav> {/* Navegación común */} </nav> {children} ); }
// 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> ); }
// 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></image> ); }
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> ); }
// components/Button.tsx import styles from './Button.module.css'; export default function Button({ children }) { return ( <button classname="{styles.button}"> {children} </button> ); }
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></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;
app/ ├── (auth)/ │ ├── login/ │ └── register/ ├── (dashboard)/ │ ├── profile/ │ └── settings/ └── (marketing)/ ├── about/ └── contact/
// 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> ); }
// 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> </div> ); }
Next.js 14 のオファー:
次のような場合に最適です。
プロジェクトで Next.js を使用していますか?どの機能が最も便利だと思いますか?コメントであなたの経験を共有してください! ?
以上がNext.js: 最も人気のある React フレームワークの決定版ガイドの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。