Next.js (1) สร้าง Project และจัดการ App Router

Web Development 20 เมษายน พ.ศ. 2567 532
Home / Articles / 801

Next.js เป็นผลงาน Fullstack React Framework จากบริษัท Vercel ที่หลายๆ คนมองว่า นี่เป็นสิ่งที่ React.js ควรจะเป็นตั้งแต่แรก เหตุที่เรามองว่ามันเป็น Fullstack Framework ก็เพราะว่า ตัว Next.js สามารถทำการประมวลผลแบบ Server-Side Rendering ได้ ในกรณีที่เป็นข้อมูลคงที่ (Static Content) ไม่จำเป็นต้องประมวลผลฝั่ง Client อย่างเดียว เหมือนที่ React เคยทำ แต่ก็ยังสามารถประมวลผลฝั่ง Client-Side ได้เหมือนเดิม กรณีที่ส่วนดังกล่าวเป็นข้อมูลแบบ Dynamic Content สามารถเปลี่ยนแปลงได้ตลอดเวลา

สร้าง Next.js Project

ในการสร้าง Next Project ใหม่ เราจำเป็นจะต้องมี Node.js, NPM ในการสร้าง Project หากเพื่อน ๆ มีแล้ว ให้ใช้คำสั่งดังนี้ ในการสร้าง Project

npx create-next-app@latest

จากนั้น Next จะถามข้อมูลเบื้องต้น ที่เราต้องตั้งค่า โดยผมจะเลือกตามนี้

✔ What is your project named? … my-test-app
✔ Would you like to use TypeScript? … เลือก Yes
✔ Would you like to use ESLint? … เลือก Yes
✔ Would you like to use Tailwind CSS? … เลือก No
✔ Would you like to use `src/` directory? … เลือก Yes
✔ Would you like to use App Router? (recommended) … เลือก Yes
✔ Would you like to customize the default import alias (@/*)? … เลือก No

เมื่อเรายืนยันไปตามนี้ ก็จะมีโฟลเดอร์ที่เป็นชื่อ Project เราเกิดขึ้นมา ของผมก็จะเป็น "my-test-app"

โครงสร้าง Folder แบบคร่าว ๆ

ข้างใน Project Folder เราก็จะประกอบไปด้วยโฟลเดอร์ ได้แก่

/src/app

เป็นโฟลเดอร์หลักที่เราจะเขียนสิ่งต่าง ๆ ลงไป

/public

ใช้เก็บไฟล์ที่จะสามารถเข้าถึงได้อย่างสาธารณะ เช่น หากผมนำไฟล์ a ไปใส่ใน /public/img/ ผมก็จะสามารถเข้าถึงไฟล์นี้ได้จาก http://.../img/a เป็นต้น

/node_modules

ใช้เก็บ Module ต่าง ๆ ที่ใช้ภายใน Next Project

แก้ไข และแสดง Hello World ในหน้าแรก

เมื่อเราใช้คำสั่งดังนี้ เพื่อสั่งให้ Project ทำงาน

npm run dev

จะพบว่าในหน้า http://localhost:3000 จะมีหน้าเว็บเกิดขึ้น เป็นหน้าเริ่มต้นของ Next เราจะสามารถแก้ไข หน้านี้ได้โดยการไปที่ไฟล์ /src/app/page.tsx โดยผมจะลบเนื้อหาในไฟล์ออก ให้เหลือส่วนที่เป็นแกนหลักของมัน ดังนี้

/src/app/page.tsx
export default function Home() { 
  return (
    <>
      <h1>Hello World!</h1>
    </>
  );
}

จากนั้นหน้าเว็บก็จะเปลี่ยนเป็น Hello World แต่ก็ยังมี CSS ที่เป็นค่าเริ่มต้นอยู่ ให้เราไปแก้ไขที่ /src/app/layout.tsx โดยการเปลี่ยน globals.css ใน import เป็นไฟล์อื่น หรือจะลบเนื้อหาเก่าใน globals.css แล้วเขียนใหม่ก็ได้

/src/app/layout.tsx
import type { Metadata } from "next";
// import { Inter } from "next/font/google";
// import "./globals.css"

export const metadata: Metadata = {
  title: "Sunny420x",
  description: "Sunny420x Personal Website.",
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  );
}

ความหมายของไฟล์ Layout.tsx

ไฟล์ layout.tsx จะเป็นไฟล์หลักที่จะเรียกใช้ไฟล์อื่น ๆ ที่อยู่ใน Folder เดียวกัน มาอยู่ในส่วน children

ส่วน metadata ก็คือ ส่วนที่เป็น title หรือ description ของเว็บไซต์ รวมถึง attribute ต่างๆ ใน <meta> ที่เรามักใช้งานกัน จะเห็นว่าในปัจจุบัน ผมได้ตั้ง Title เป็น "Sunny420x"

สร้างหน้าอื่น ๆ ด้วย App Router

ในการสร้างหน้าใหม่ใน Next.js นั้นค่อนข้างง่ายเลยทีเดียว เป็นการสร้างโฟลเดอร์ย่อย ๆ ภายใน /src/app เท่านั้น

สมมุติว่าผมต้องการ สร้างหน้าที่เข้าถึงด้วย URL: /about ผมก็จะไปสร้างโฟลเดอร์ about ไว้ภายใน /src/app และสร้างไฟล์ page.tsx ไว้ข้างใน /src/app/about แทน โดยมีเนื้อหาดังนี้

/src/app/about/page.tsx
export default function About() {
    return(
      <>
        <h1>About Page</h1>
      </>
    )
}

เมื่อเราใส่ export default เข้าไป นั่นหมายถึงเราต้องการจะให้ Component นี้เป็น Component หลักที่จะแสดง เมื่อเปิด URL: /about ขึ้นมา

สร้าง Component ใหม่ และเรียกใช้งาน

ในการออกแบบการเขียนเว็บไซต์ด้วย React เราจะแบ่งส่วนต่าง ๆ ออกเป็น Component ที่อิสระต่อกัน ตัวอย่าง ในหน้า /about ผมจะสร้าง Component ใหม่ชื่อ "MyInfo" ซึ่งจะเป็นข้อมูลที่เราจะดึงมาแสดงใน default component ของเรา ซึ่งในกรณีนี้คือ "About" เราจะเขียนดังนี้

/src/app/about/page.tsx
export function MyInfo() {
    return (
        <>
            <p>Hi! My name is Sunny!</p>
        <>
    )
}
export default function About() {
    return(
      <>
        <h1>About Page</h1>
      </>
    )
}

และจะเรียกมาแสดง โดยเพิ่ม <MyInfo /> เข้าไป

/src/app/about/page.tsx
export function MyInfo() {
    return (
        <>
            <p>Hi! My name is Sunny!</p>
        <>
    )
}
export default function About() {
    return(
      <>
        <h1>About Page</h1>
        <MyInfo />
      </>
    )
}

แต่เมื่อเราไปที่ /about แล้ว ส่วนที่เป็น Title ของเว็บ ยังจะแสดงผลเป็น "Sunny420x" อยู่ เนื่องจากใน /src/app/about ยังใช้ metadata จากไฟล์ /src/app/layout.tsx เราจะแก้ปัญหาโดยการสร้างไฟล์ layout.tsx ข้างในโฟลเดอร์ /src/app/about เพื่อจัดการ Route นี้โดยเฉพาะ

/src/app/about/layout.tsx
import type { Metadata } from "next";

export const metadata: Metadata = {
  title: "About | Sunny420x",
  description: "Sunny420x Personal Website.",
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  );
}

ทีนี้เมื่อเราเข้า /about เราก็จะได้ Title "About | Sunny420x" ตามที่เราต้องการแล้ว

ในบทความต่อไปผมจะพาไปแนะนำการ Fetch ข้อมูลจาก Backend รวมถึงการใช้ useState, useEffects ในการติดตามสถานะการ fetch ข้อมูลมาแสดงกัน

อ้างอิง:

nextjs.org/docs

Profile Picture.
  • Name (Pen name): Sunny Jirakit (Sunny420x)
  • Study: Bachelor Degree of Computer Science from Chiang Mai Rajabhat University
  • Personality: Architect (INTJ-T)
  • Experience: JavaScript,  Angular.js, React.js, Next.js  Express.js, Unity C#, Socket.io