#React เบื้องต้น: เริ่มต้นพัฒนา Web Application ด้วย React

React เป็น JavaScript Library สำหรับสร้าง User Interface (UI) โดยเฉพาะ Web Application ที่มีข้อมูลเปลี่ยนแปลงแบบ Interactive เช่น Dashboard, ระบบสมาชิก, ระบบร้านค้าออนไลน์ หรือ Single Page Application

แนวคิดสำคัญของ React คือการแบ่งหน้าจอออกเป็นส่วนย่อยที่เรียกว่า Component แล้วนำ Component หลาย ๆ ตัวมาประกอบกันเป็นระบบ

App
├── Navbar
├── ProductList
│   ├── ProductCard
│   ├── ProductCard
│   └── ProductCard
└── Footer

ข้อดีของแนวคิดแบบ Component คือ

  • แบ่งโค้ดออกเป็นส่วนย่อยที่ดูแลได้ง่าย
  • นำ Component กลับมาใช้ซ้ำได้
  • แยกหน้าที่ของแต่ละส่วนได้ชัดเจน
  • เหมาะกับระบบที่ UI เปลี่ยนตามข้อมูล
  • ทำงานร่วมกับ JavaScript และ TypeScript ได้ดี

#สิ่งที่ควรรู้ก่อนเริ่ม React

ก่อนเรียน React ควรมีพื้นฐานดังนี้

  • HTML
  • CSS
  • JavaScript
  • ES Modules
  • Arrow Function
  • Object และ Array
  • Destructuring
  • map()
  • filter()
  • async/await

ตัวอย่าง JavaScript ที่พบบ่อยใน React

const user = {
  name: "Alice",
  age: 22,
}

const { name, age } = user

const numbers = [1, 2, 3]

const doubled = numbers.map((number) => number * 2)

console.log(doubled)

#1. การสร้าง React Project

สำหรับผู้เริ่มต้นสามารถสร้าง React Project ด้วย Vite

ตรวจสอบ Node.js

node -v
npm -v

สร้าง Project

npm create vite@latest my-react-app -- --template react

เข้าไปยัง Project

cd my-react-app

ติดตั้ง Dependency

npm install

เริ่ม Development Server

npm run dev

จากนั้นเปิด URL ที่ Vite แสดงใน Terminal เช่น

http://localhost:5173

#2. โครงสร้าง React Project

โครงสร้างพื้นฐานของ React Project ที่สร้างด้วย Vite มีลักษณะประมาณนี้

my-react-app/
├── public/
├── src/
│   ├── assets/
│   ├── App.css
│   ├── App.jsx
│   ├── index.css
│   └── main.jsx
├── index.html
├── package.json
└── vite.config.js

ไฟล์สำคัญ ได้แก่

ไฟล์ หน้าที่
main.jsx จุดเริ่มต้นของ React Application
App.jsx Root Component หลัก
App.css CSS สำหรับ App
index.css Global CSS
package.json Dependency และ Script ของ Project
vite.config.js Configuration ของ Vite

#3. Component คืออะไร

React Application ประกอบขึ้นจาก Component

Component สามารถเขียนในรูปแบบ JavaScript Function

function Hello() {
  return <h1>Hello React</h1>
}

export default Hello

ชื่อ Component ควรขึ้นต้นด้วยตัวอักษรพิมพ์ใหญ่

ตัวอย่าง

Hello
Navbar
UserCard
ProductList

เมื่อเรียกใช้ Component สามารถเขียนคล้าย HTML Tag

function App() {
  return (
    <div>
      <Hello />
      <Hello />
    </div>
  )
}

export default App

React จึงช่วยให้เราสามารถแยก UI เป็นส่วนย่อยและนำกลับมาใช้ซ้ำได้ง่าย


#4. JSX

JSX เป็น Syntax ที่ช่วยให้สามารถเขียนโครงสร้าง UI คล้าย HTML ภายใน JavaScript

ตัวอย่าง

function App() {
  return (
    <div>
      <h1>Hello React</h1>
      <p>Learning React</p>
    </div>
  )
}

export default App

สามารถนำ JavaScript Expression มาใช้ภายใน JSX ด้วย {}

function App() {
  const name = "Alice"

  return <h1>Hello {name}</h1>
}

export default App

สามารถคำนวณค่าภายใน JSX ได้เช่นกัน

function App() {
  const price = 100
  const quantity = 3

  return <p>Total: {price * quantity}</p>
}

#JSX ต้องมี Parent Element

ไม่ควรเขียนแบบนี้

return (
  <h1>Hello</h1>
  <p>React</p>
)

ควรใช้ Parent Element

return (
  <div>
    <h1>Hello</h1>
    <p>React</p>
  </div>
)

หรือใช้ Fragment

return (
  <>
    <h1>Hello</h1>
    <p>React</p>
  </>
)

#5. Props

Props ใช้สำหรับส่งข้อมูลจาก Parent Component ไปยัง Child Component

ตัวอย่าง

function Welcome({ name }) {
  return <h2>Hello {name}</h2>
}

เรียกใช้

function App() {
  return (
    <>
      <Welcome name="Alice" />
      <Welcome name="Bob" />
    </>
  )
}

สามารถส่ง Props หลายค่าได้

function UserCard({ name, email, role }) {
  return (
    <div>
      <h2>{name}</h2>
      <p>{email}</p>
      <p>{role}</p>
    </div>
  )
}

เรียกใช้

<UserCard
  name="Alice"
  email="alice@example.com"
  role="Developer"
/>

แนวคิดการไหลของข้อมูล

Parent Component
       │
       │ Props
       ▼
Child Component

React ใช้แนวคิด One-Way Data Flow คือข้อมูลมักไหลจาก Component ด้านบนลงสู่ Component ด้านล่าง


#6. State

State คือข้อมูลภายใน Component ที่สามารถเปลี่ยนแปลงได้

React มี Hook ชื่อ useState สำหรับจัดการ State

import { useState } from "react"

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

  return (
    <div>
      <p>Count: {count}</p>

      <button onClick={() => setCount(count + 1)}>
        Increase
      </button>
    </div>
  )
}

export default Counter

โครงสร้างของ useState

const [state, setState] = useState(initialValue)

ตัวอย่าง

const [name, setName] = useState("")
const [count, setCount] = useState(0)
const [isLogin, setIsLogin] = useState(false)

เมื่อ State เปลี่ยน React จะ Render Component ใหม่เพื่อให้ UI สอดคล้องกับข้อมูลล่าสุด

State Change
     │
     ▼
React Render
     │
     ▼
UI Updated

#7. Event Handling

React รองรับ Event หลายชนิด เช่น

  • onClick
  • onChange
  • onSubmit
  • onMouseEnter
  • onKeyDown

ตัวอย่าง onClick

function Button() {
  function handleClick() {
    alert("Hello React")
  }

  return (
    <button onClick={handleClick}>
      Click
    </button>
  )
}

สิ่งสำคัญคือควรเขียน

onClick={handleClick}

ไม่ใช่

onClick={handleClick()}

เพราะ React ต้องการ Function Reference เพื่อนำไปเรียกเมื่อเกิด Event


#8. Form และ Input

ตัวอย่าง Controlled Input

import { useState } from "react"

function App() {
  const [name, setName] = useState("")

  return (
    <div>
      <input
        type="text"
        value={name}
        onChange={(event) => setName(event.target.value)}
      />

      <p>Hello {name}</p>
    </div>
  )
}

export default App

การทำงาน

User Input
    │
    ▼
onChange
    │
    ▼
setName()
    │
    ▼
State Changed
    │
    ▼
Render UI

#9. Conditional Rendering

React สามารถแสดง UI ตามเงื่อนไขได้

#ใช้ if

function UserStatus({ isLogin }) {
  if (isLogin) {
    return <p>Welcome</p>
  }

  return <p>Please Login</p>
}

#ใช้ Ternary Operator

function UserStatus({ isLogin }) {
  return (
    <p>
      {isLogin ? "Welcome" : "Please Login"}
    </p>
  )
}

#ใช้ Logical AND

function Message({ hasMessage }) {
  return (
    <>
      {hasMessage && <p>You have a new message</p>}
    </>
  )
}

#10. การแสดง List

สมมติมีข้อมูลผู้ใช้

const users = [
  { id: 1, name: "Alice" },
  { id: 2, name: "Bob" },
  { id: 3, name: "Charlie" },
]

สามารถใช้ map() เพื่อสร้าง UI

function UserList() {
  const users = [
    { id: 1, name: "Alice" },
    { id: 2, name: "Bob" },
    { id: 3, name: "Charlie" },
  ]

  return (
    <ul>
      {users.map((user) => (
        <li key={user.id}>
          {user.name}
        </li>
      ))}
    </ul>
  )
}

ควรใช้ค่า Unique เป็น key

key={user.id}

ไม่ควรใช้ Array Index หากรายการสามารถเพิ่ม ลบ หรือเรียงลำดับใหม่ได้


#11. React Hooks

Hook คือ Function ที่ช่วยให้ Function Component สามารถใช้งานความสามารถต่าง ๆ ของ React ได้

Hook ที่พบบ่อย ได้แก่

Hook ใช้งาน
useState จัดการ State
useEffect Synchronize กับระบบภายนอก
useContext อ่านข้อมูลจาก Context
useRef เก็บ Reference หรือค่าที่ไม่ต้อง Render ใหม่
useMemo Cache ค่าที่คำนวณ
useCallback Cache Function

สำหรับผู้เริ่มต้นแนะนำให้เรียนตามลำดับ

useState
   │
   ▼
useEffect
   │
   ▼
useContext
   │
   ▼
Custom Hooks

#12. useEffect เบื้องต้น

useEffect ใช้เมื่อ Component ต้อง Synchronize กับระบบภายนอก เช่น

  • REST API
  • Browser API
  • Timer
  • Subscription
  • WebSocket

ตัวอย่างเปลี่ยน Title ของ Browser

import { useEffect, useState } from "react"

function App() {
  const [count, setCount] = useState(0)

  useEffect(() => {
    document.title = `Count ${count}`
  }, [count])

  return (
    <button onClick={() => setCount(count + 1)}>
      Count: {count}
    </button>
  )
}

export default App

ในตัวอย่างนี้

[count]

คือ Dependency Array

Effect จะทำงานเมื่อค่า count เปลี่ยน


#13. การเรียก REST API

สามารถเรียก REST API ด้วย fetch()

import { useEffect, useState } from "react"

function UserList() {
  const [users, setUsers] = useState([])

  useEffect(() => {
    async function loadUsers() {
      const response = await fetch(
        "https://jsonplaceholder.typicode.com/users"
      )

      const data = await response.json()

      setUsers(data)
    }

    loadUsers()
  }, [])

  return (
    <ul>
      {users.map((user) => (
        <li key={user.id}>
          {user.name}
        </li>
      ))}
    </ul>
  )
}

export default UserList

Flow การทำงาน

Component Render
       │
       ▼
    useEffect
       │
       ▼
    Fetch API
       │
       ▼
 setUsers(data)
       │
       ▼
 State Changed
       │
       ▼
 React Render

ในระบบจริงควรเพิ่มการจัดการ

  • Loading
  • Error
  • Authentication
  • Request Cancellation
  • API Service Layer
  • Caching

#14. Mini Project: Counter

ตัวอย่าง Project เล็ก ๆ สำหรับฝึก React

import { useState } from "react"

function App() {
  const [count, setCount] = useState(0)

  const increase = () => {
    setCount(count + 1)
  }

  const decrease = () => {
    setCount(count - 1)
  }

  const reset = () => {
    setCount(0)
  }

  return (
    <div>
      <h1>React Counter</h1>

      <h2>{count}</h2>

      <button onClick={decrease}>
        -
      </button>

      <button onClick={reset}>
        Reset
      </button>

      <button onClick={increase}>
        +
      </button>
    </div>
  )
}

export default App

สิ่งที่ได้ฝึก

  • Component
  • useState
  • Event
  • State Update
  • JSX

#15. Mini Project: Todo List

import { useState } from "react"

function App() {
  const [task, setTask] = useState("")
  const [tasks, setTasks] = useState([])

  function addTask() {
    if (!task.trim()) {
      return
    }

    const newTask = {
      id: crypto.randomUUID(),
      title: task,
    }

    setTasks([...tasks, newTask])
    setTask("")
  }

  function removeTask(id) {
    setTasks(
      tasks.filter((task) => task.id !== id)
    )
  }

  return (
    <div>
      <h1>Todo List</h1>

      <input
        value={task}
        onChange={(event) =>
          setTask(event.target.value)
        }
      />

      <button onClick={addTask}>
        Add
      </button>

      <ul>
        {tasks.map((task) => (
          <li key={task.id}>
            {task.title}

            <button
              onClick={() => removeTask(task.id)}
            >
              Delete
            </button>
          </li>
        ))}
      </ul>
    </div>
  )
}

export default App

Project นี้ครอบคลุมพื้นฐานหลายเรื่อง ได้แก่

  • State
  • Event
  • Form
  • Controlled Input
  • map()
  • filter()
  • List Key

#16. การแยก Component

เมื่อระบบเริ่มใหญ่ขึ้น ไม่ควรเขียนทุกอย่างไว้ใน App.jsx

ตัวอย่างโครงสร้าง

src/
├── components/
│   ├── Navbar.jsx
│   ├── UserCard.jsx
│   └── Footer.jsx
├── pages/
│   ├── Home.jsx
│   └── About.jsx
├── App.jsx
└── main.jsx

ตัวอย่าง UserCard.jsx

function UserCard({ name, email }) {
  return (
    <div>
      <h2>{name}</h2>
      <p>{email}</p>
    </div>
  )
}

export default UserCard

นำมาใช้ใน App.jsx

import UserCard from "./components/UserCard"

function App() {
  return (
    <UserCard
      name="Alice"
      email="alice@example.com"
    />
  )
}

export default App

#17. Props กับ State ต่างกันอย่างไร

หัวข้อ Props State
แหล่งข้อมูล รับจาก Parent อยู่ภายใน Component
แก้ไขโดย Component ไม่ควรแก้โดยตรง เปลี่ยนผ่าน Setter
ใช้สำหรับ ส่งข้อมูล เก็บข้อมูลที่เปลี่ยนแปลง
ตัวอย่าง name, price count, isLogin

สรุปง่าย ๆ

Props = ข้อมูลที่ Component รับเข้ามา

State = ข้อมูลที่ Component จัดการเอง

#18. Data Flow ของ React

React ใช้แนวคิด One-Way Data Flow

App
 │
 │ props
 ▼
UserList
 │
 │ props
 ▼
UserCard

ถ้า Child Component ต้องการให้ Parent เปลี่ยน State สามารถส่ง Callback Function ลงมาเป็น Props

function Child({ onDelete }) {
  return (
    <button onClick={onDelete}>
      Delete
    </button>
  )
}

#19. แนวทางการเรียน React

ลำดับการเรียนที่แนะนำ

HTML / CSS / JavaScript
          │
          ▼
         JSX
          │
          ▼
      Component
          │
          ▼
        Props
          │
          ▼
        State
          │
          ▼
        Events
          │
          ▼
Conditional Rendering
          │
          ▼
         Lists
          │
          ▼
         Forms
          │
          ▼
         Hooks
          │
          ▼
       REST API
          │
          ▼
       Routing
          │
          ▼
   State Management

Project ที่เหมาะสำหรับฝึก

  1. Counter
  2. Todo List
  3. Calculator
  4. Notes App
  5. Product List
  6. User Management
  7. Weather App
  8. CRUD Application
  9. Dashboard
  10. Shopping Cart

#20. คำสั่งสำคัญ

สร้าง Project

npm create vite@latest my-react-app -- --template react

ติดตั้ง Dependency

npm install

Run Development Server

npm run dev

Build Production

npm run build

Preview Production Build

npm run preview

#สรุป

หัวใจสำคัญของ React สำหรับผู้เริ่มต้นประกอบด้วย

React
 │
 ├── Component
 ├── JSX
 ├── Props
 ├── State
 ├── Events
 ├── Conditional Rendering
 ├── Lists
 ├── Forms
 └── Hooks

แนวคิดสำคัญสามารถสรุปได้ว่า

UI เปลี่ยนตาม State

เมื่อ State เปลี่ยน React จะ Render UI ใหม่ให้ตรงกับข้อมูลล่าสุด

ดังนั้นก่อนก้าวไปสู่ React Router, Zustand, TanStack Query, Testing หรือ Framework อย่าง Next.js ควรให้คล่องกับ

  • Component
  • Props
  • State
  • Events
  • Forms
  • List Rendering
  • Hooks

เมื่อพื้นฐานเหล่านี้แน่นแล้ว การพัฒนา React Application ที่มีขนาดใหญ่ขึ้นจะเข้าใจได้ง่ายมากขึ้น


#แหล่งศึกษาเพิ่มเติม