แสดงบทความที่มีป้ายกำกับ CSR แสดงบทความทั้งหมด
แสดงบทความที่มีป้ายกำกับ CSR แสดงบทความทั้งหมด

วันศุกร์ที่ 28 กุมภาพันธ์ พ.ศ. 2568

การใช้ useEffect และ useState สำหรับ Client-side Rendering (CSR)

ถ้าคุณเป็นสาย React น่าจะคุ้นเคยกับการใช้ useState และ useEffect กันอยู่แล้ว แต่เคยสงสัยไหมว่า เวลาเราทำ Client-side Rendering (CSR) ควรใช้สองตัวนี้ยังไงให้ถูกต้อง?

ในบทความนี้ เราจะมาดูวิธีใช้ useState และ useEffect ในการจัดการข้อมูลแบบ CSR (Client-side Rendering) พร้อมตัวอย่างโค้ดจริง และข้อควรระวังที่ต้องระวัง ถ้าพร้อมแล้ว ไปดูกันเลย! 🚀

🎯 Client-side Rendering (CSR) คืออะไร?

ก่อนจะไปดู useState และ useEffect มาทำความเข้าใจ CSR (Client-side Rendering) กันก่อน

📌 CSR คือการเรนเดอร์หน้าเว็บบนฝั่งไคลเอนต์ (Client-side) โดยใช้ JavaScript ซึ่งหมายความว่า ทุกอย่างถูกโหลดผ่านเบราว์เซอร์ แทนที่จะให้เซิร์ฟเวอร์ส่งหน้า HTML มาให้แบบสมบูรณ์

🔍 ลักษณะของ CSR:

  • เมื่อเข้าเว็บครั้งแรก เบราว์เซอร์จะโหลดไฟล์ HTML + JavaScript
  • JavaScript จะรันบนฝั่งไคลเอนต์ เพื่อสร้าง UI และดึงข้อมูลจาก API
  • เหมาะกับแอปที่ต้องการ อินเตอร์แอคทีฟสูง เช่น Dashboard หรือ Web App
  • แต่ SEO อาจไม่ดี เพราะหน้าเว็บไม่มีข้อมูล HTML ให้บอทอ่าน (ต้องใช้ Next.js + SSR/SSG แก้ปัญหา)


🛠 การใช้ useState และ useEffect สำหรับ CSR

📌 useState คืออะไร?

useState เป็น React Hook ที่ใช้จัดการ state (ข้อมูลที่เปลี่ยนแปลงได้) ในคอมโพเนนต์ ฟังก์ชันนี้ช่วยให้เราสร้างตัวแปร state และอัปเดตค่าได้ง่าย ๆ

📌 useEffect คืออะไร?

useEffect เป็น React Hook ที่ใช้จัดการ side effects เช่น

  • เรียก API
  • เปลี่ยนชื่อเอกสาร (document.title)
  • ตั้งค่า setTimeout หรือ setInterval


🏗 ตัวอย่างการใช้ useState และ useEffect ใน CSR

มาดูกันว่า เราสามารถใช้ useState และ useEffect ใน CSR ได้ยังไง โดยสมมติว่าเราต้องการ ดึงข้อมูลผู้ใช้จาก API และแสดงผลในเว็บ

1. โหลดข้อมูลจาก API ด้วย useEffect

import React, { useState, useEffect } from 'react';

const UsersList = () => {
  const [users, setUsers] = useState([]); // ใช้ useState เก็บข้อมูลผู้ใช้
  const [loading, setLoading] = useState(true); // ใช้ state เช็กว่ากำลังโหลดข้อมูลอยู่ไหม

  useEffect(() => {
    // ดึงข้อมูลจาก API เมื่อคอมโพเนนต์โหลดครั้งแรก
    fetch('https://jsonplaceholder.typicode.com/users')
      .then((response) => response.json())
      .then((data) => {
        setUsers(data); // อัปเดต state
        setLoading(false); // ปิดสถานะ loading
      });
  }, []); // ใส่ [] หมายความว่าจะรันแค่ครั้งเดียวตอนโหลดหน้า

  return (
    <div>
      <h1>รายชื่อผู้ใช้</h1>
      {loading ? <p>กำลังโหลดข้อมูล...</p> : null}
      <ul>
        {users.map((user) => (
          <li key={user.id}>{user.name}</li>
        ))}
      </ul>
    </div>
  );
};

export default UsersList;

🔍 อธิบายโค้ด

  • ใช้ useState([]) เพื่อเก็บข้อมูลผู้ใช้
  • ใช้ useEffect เพื่อเรียก API ตอนคอมโพเนนต์โหลดครั้งแรก
  • ใช้ setUsers(data) เพื่ออัปเดตข้อมูล
  • ใช้ setLoading(false) เพื่อปิดสถานะโหลด


2. ใช้ useEffect จัดการ Event Listener

สมมติว่าเราต้องการให้หน้าเว็บ เช็กขนาดหน้าจอ (window size) และอัปเดตทุกครั้งที่เปลี่ยนขนาด

import React, { useState, useEffect } from 'react';

const WindowSize = () => {
  const [width, setWidth] = useState(window.innerWidth);

  useEffect(() => {
    const handleResize = () => setWidth(window.innerWidth);

    window.addEventListener('resize', handleResize);

    return () => {
      window.removeEventListener('resize', handleResize); // ลบ Event Listener ตอนคอมโพเนนต์ unmount
    };
  }, []);

  return (
    <div>
      <h1>ขนาดหน้าจอ: {width}px</h1>
    </div>
  );
};

export default WindowSize;

🔍 อธิบายโค้ด

  • ใช้ useState เพื่อเก็บค่าความกว้างของหน้าจอ
  • ใช้ useEffect เพิ่ม event listener resize ตอนโหลด
  • ใช้ return () => {} เพื่อลบ event listener ตอนคอมโพเนนต์ถูกถอดออก


🔥 ข้อควรระวังในการใช้ useEffect และ useState

⚠️ 1. อย่าดึง API ใน useEffect แบบไม่มี Dependency Array

ถ้าคุณลืมใส่ [] มันจะรันซ้ำ ทุกครั้งที่คอมโพเนนต์ re-render ทำให้ API ถูกเรียกหลายรอบเกินไป

❌ โค้ดผิด:

useEffect(() => {
  fetchData(); // จะเรียก API ทุกครั้งที่ state เปลี่ยน
});

✅ โค้ดที่ถูกต้อง:

useEffect(() => {
  fetchData(); // เรียก API แค่ครั้งเดียว
}, []);

⚠️ 2. อย่าอัปเดต state ใน useEffect โดยไม่มีเงื่อนไข

ถ้าเราอัปเดต state โดยไม่มีเงื่อนไข มันจะทำให้เกิด Infinite Loop ได้

❌ โค้ดผิด:

useEffect(() => {
  setCount(count + 1); // ทำให้เกิดลูป เพราะการอัปเดต state ทำให้ useEffect รันใหม่
}, [count]);

✅ โค้ดที่ถูกต้อง:

useEffect(() => {
  if (count < 10) setCount(count + 1);
}, [count]); // ตรวจสอบก่อนอัปเดต state


📌 สรุป

  • useState ใช้เก็บข้อมูลที่เปลี่ยนแปลงได้ในคอมโพเนนต์
  • useEffect ใช้ดึงข้อมูลจาก API, จัดการ Event Listener, และทำงานที่ต้องเกิดหลังจาก render
  • CSR เหมาะกับเว็บที่ต้องการโต้ตอบเยอะ แต่ไม่เหมาะกับ SEO
  • ควรระวังการใช้ useEffect ไม่ให้เกิด Infinite Loop หรือ API ถูกเรียกซ้ำ

ถ้าคุณเข้าใจการใช้ useState และ useEffect แล้ว คุณสามารถพัฒนาเว็บแบบ CSR ได้อย่างมีประสิทธิภาพ 🚀

วันจันทร์ที่ 24 กุมภาพันธ์ พ.ศ. 2568

ความแตกต่างระหว่าง SSR, SSG และ CSR ใน Next.js – อธิบายแบบง่ายๆ

Next.js เป็นเฟรมเวิร์กที่ทำให้การพัฒนาเว็บแอปด้วย React ง่ายและเร็วขึ้น แต่เมื่อพูดถึงการเรนเดอร์หน้าเว็บใน Next.js หลายคนอาจจะงงกับคำว่า SSR (Server-Side Rendering), SSG (Static Site Generation) และ CSR (Client-Side Rendering) ว่าแต่ละตัวต่างกันยังไง และควรเลือกใช้อะไรดี วันนี้เรามาเคลียร์ให้กระจ่าง!

🎭 อะไรคือ SSR, SSG และ CSR?

ถ้าจะเข้าใจง่าย ๆ ให้นึกถึงวิธีที่หน้าเว็บถูกโหลดขึ้นมาบนหน้าจอของผู้ใช้ มันมี 3 วิธีหลัก ๆ คือ

  • CSR (Client-Side Rendering) → โหลดหน้าเว็บแบบเปล่า ๆ แล้วให้ JavaScript ไปดึงข้อมูลมาเติมเอง
  • SSR (Server-Side Rendering) → โหลดข้อมูลที่ฝั่งเซิร์ฟเวอร์ แล้วส่ง HTML ที่มีข้อมูลมาครบให้ผู้ใช้
  • SSG (Static Site Generation) → สร้าง HTML ทั้งหมดตั้งแต่ตอน build และเสิร์ฟแบบ static


มาเจาะลึกแต่ละตัวกัน 🔍

1. CSR (Client-Side Rendering) – โหลดข้อมูลที่ฝั่งผู้ใช้

📌 มันคืออะไร?

CSR (Client-Side Rendering) เป็นแนวทางการโหลดหน้าเว็บแบบดั้งเดิมของ React คือ

  • โหลดโครงสร้างหน้าเว็บมาก่อน
  • จากนั้นใช้ JavaScript ไปดึงข้อมูลจาก API หรือ Database มาเติมที่ฝั่งผู้ใช้


🏗 ตัวอย่างโค้ด CSR ใน Next.js

import { useEffect, useState } from "react";

export default function CSRPage() {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch("https://jsonplaceholder.typicode.com/posts/1")
      .then((res) => res.json())
      .then((data) => setData(data));
  }, []);

  if (!data) return <p>Loading...</p>;

  return (
    <div>
      <h1>{data.title}</h1>
      <p>{data.body}</p>
    </div>
  );
}

✅ ข้อดีของ CSR
✔️ โหลดเร็วถ้าเนื้อหาไม่เยอะ
✔️ ประสบการณ์ใช้งานลื่นไหล (เพราะไม่ต้องรีเฟรชหน้า)
✔️ ใช้งานง่ายมาก


❌ ข้อเสียของ CSR

❌ SEO ไม่ดี เพราะต้องรอให้ข้อมูลโหลดมาก่อน
❌ โหลดข้อมูลช้ากว่า เพราะต้องดึง API เพิ่ม


2. SSR (Server-Side Rendering) – เรนเดอร์บนเซิร์ฟเวอร์

📌 มันคืออะไร?

SSR (Server-Side Rendering) ทำงานตรงข้ามกับ CSR คือ

  • เมื่อมีคนเข้าเว็บ Next.js จะไปดึงข้อมูลจากเซิร์ฟเวอร์มาก่อน
  • แล้วสร้าง HTML พร้อมข้อมูล ส่งให้ผู้ใช้เลย
  • ทำให้หน้าเว็บแสดงผลพร้อมข้อมูลตั้งแต่แรก


🏗 ตัวอย่างโค้ด SSR ใน Next.js

export async function getServerSideProps() {
  const res = await fetch("https://jsonplaceholder.typicode.com/posts/1");
  const data = await res.json();

  return {
    props: { data },
  };
}

export default function SSRPage({ data }) {
  return (
    <div>
      <h1>{data.title}</h1>
      <p>{data.body}</p>
    </div>
  );
}


✅ ข้อดีของ SSR
✔️ SEO ดีมาก เพราะข้อมูลมาเป็น HTML พร้อมเลย
✔️ ใช้ได้กับเนื้อหาที่เปลี่ยนบ่อย เช่น ข่าว หรือ Dashboard
✔️ ไม่ต้องรอโหลดข้อมูลที่ฝั่งผู้ใช้


❌ ข้อเสียของ SSR
❌ โหลดช้ากว่า SSG เพราะต้องรอให้เซิร์ฟเวอร์ดึงข้อมูลก่อน
❌ ถ้ามีคนเข้าเยอะ อาจทำให้เซิร์ฟเวอร์ช้า


3. SSG (Static Site Generation) – เรนเดอร์ตั้งแต่ตอน build

📌 มันคืออะไร?

SSG (Static Site Generation) เป็นการสร้าง HTML ล่วงหน้าตั้งแต่ตอน build เวลา deploy หน้าเว็บก็จะเป็น ไฟล์ HTML Static ที่พร้อมใช้งาน

🏗 ตัวอย่างโค้ด SSG ใน Next.js

export async function getStaticProps() {
  const res = await fetch("https://jsonplaceholder.typicode.com/posts/1");
  const data = await res.json();

  return {
    props: { data },
  };
}

export default function SSGPage({ data }) {
  return (
    <div>
      <h1>{data.title}</h1>
      <p>{data.body}</p>
    </div>
  );
}


✅ ข้อดีของ SSG
✔️ เร็วมาก เพราะหน้าเว็บถูกสร้างล่วงหน้า
✔️ รองรับ SEO ดีเยี่ยม
✔️ เซิร์ฟเวอร์ไม่ต้องทำงานหนัก


❌ ข้อเสียของ SSG
❌ ใช้กับข้อมูลที่เปลี่ยนแปลงตลอดไม่ได้ เช่น Dashboard หรือ News Feed
❌ ถ้าเปลี่ยนข้อมูล ต้อง build ใหม่


🎯 สรุปว่าเลือกอะไรดี?


วิธี โหลดเร็วไหม? 🚀 SEO ดีไหม? 🌍 เหมาะกับอะไร?
CSR (Client-Side Rendering) ปานกลาง แย่ เว็บที่ไม่เน้น SEO เช่น Dashboard
SSR (Server-Side Rendering) ช้าแต่ได้ข้อมูลครบ ดี เว็บที่มีข้อมูลเปลี่ยนบ่อย เช่น ข่าว
SSG (Static Site Generation) เร็วที่สุด ดีมาก เว็บที่ข้อมูลเปลี่ยนน้อย เช่น บล็อก


✅ แนวทางแนะนำ
  • ใช้ CSR ถ้าเน้น UX และไม่แคร์ SEO
  • ใช้ SSR ถ้าต้องอัปเดตข้อมูลบ่อย และต้องการ SEO
  • ใช้ SSG ถ้าต้องการความเร็วและ SEO ดี


🚀 Hybrid Approach – ใช้หลายแบบร่วมกัน

Next.js ไม่ได้บังคับให้ใช้แค่วิธีเดียว! เราสามารถใช้ SSR, SSG และ CSR ร่วมกันได้ เช่น

  • ใช้ SSG สำหรับหน้าเว็บหลัก เช่น หน้า About, หน้า Blog
  • ใช้ SSR สำหรับหน้าที่เปลี่ยนข้อมูลบ่อย เช่น หน้า Dashboard
  • ใช้ CSR สำหรับฟีเจอร์ที่ไม่เกี่ยวกับ SEO เช่น หน้า Chat หรือ Cart


ตัวอย่างโค้ด Hybrid Approach

export async function getStaticProps() {
  const res = await fetch("https://jsonplaceholder.typicode.com/posts");
  const posts = await res.json();

  return {
    props: { posts },
    revalidate: 10, // อัปเดตข้อมูลทุก 10 วินาที
  };
}


🔥 สรุป

  • CSR → โหลดที่ฝั่งผู้ใช้ (เร็ว แต่ไม่ดีต่อ SEO)
  • SSR → โหลดที่ฝั่งเซิร์ฟเวอร์ (SEO ดี แต่โหลดช้ากว่า)
  • SSG → โหลดล่วงหน้าตอน build (เร็วและ SEO ดีมาก)

    Next.js ใช้หลายแบบร่วมกันได้ 🚀

การใช้ Image Optimization ใน Next.js: โหลดไว SEO ดี ประหยัดแบนด์วิธ!

เคยเจอปัญหาเว็บโหลดช้าเพราะรูปภาพขนาดใหญ่หรือเปล่า? 📷 ถ้าใช่ Next.js มีฟีเจอร์ Image Optimization ที่ช่วยให้รูปภาพโหลดเร็วขึ้น อัตโนมัติ ไม...