Back to notes
mastery-frontend-react
Featured

React Hooks Mastery: เข้าใจกลไกและไขความลับระดับ Senior

ไม่ได้เป็นแค่ฟังก์ชัน! เจาะลึกกลไก Linked List เบื้องหลัง Hooks, วิธีแก้ปัญหา Stale Closure ที่ทำให้จูเนียร์กุมขมับ และการใช้ Memoization อย่างมีกลยุทธ์

January 30, 20263 min read readNNexis by Seereen

🛑 1. The Problem First: "ทำไมค่าใน Log ถึงไม่อัปเดต?"

ลองนึกถึงวันที่คุณสร้างปุ่มนับเลขง่ายๆ แล้วอยากจะ Log ค่าออกมาดูหลังจากผ่านไป 3 วินาที:

HLJS TSX
// ❌ Naive Approach: กับดัก Stale Closure
function Counter() {
    const [count, setCount] = useState(0);
    const handleLog = () => {
        setTimeout(() => {
            console.log("Count ปัจจุบันคือ:", count);
        }, 3000);
    };
    return (
        <button onClick={() => { setCount(count + 1); handleLog(); }}>
           คลิกเพื่อเพิ่มและ Log
        </button>
    );
}
// 🌋 พัง! ต่อให้คุณรัวคลิกจนเลขไปถึง 10 แต่ใน Console จะโชว์เลข 0
# เสมอ เพราะฟังก์ชัน 'จำ' ค่า count ณ วินาทีที่มันถูกสร้าง (Closure)
# นี่คือสาเหตุที่โปรเจกต์ใหญ่ๆ มักจะมีบั๊กที่หาตัวยากครับ

ปัญหา: Hooks พึ่งพาความเข้าใจเรื่อง Scope และ Memory Management อย่างสูง การไม่เข้าใจว่า React 'จำ' ของทุุกอย่างไว้ใน Array ลับๆ จะทำให้คุณเจอพฤติกรรมแปลกๆ ที่แก้ยังไงก็ไม่หายครับ


💡 2. Real-Life Analogy: ลิ้นชักเก็บของในสำนักงาน

  • Rules of Hooks: เหมือน "ลำดับของลิ้นชัก". ลิ้นชักที่ 1 เก็บชื่อ, ลิ้นชักที่ 2 เก็บอายุ ถ้าวันหนึ่งคุณเดินเข้าไปแล้วบอกว่า "วันนี้ไม่ต้องเอาลิ้นชักที่ 1 ออกมา" พนักงานจะหยิบลิ้นชักถัดไปมาให้คุณแทน ผลคือคุณจะเอาอายุมาใส่ในช่องชื่อ (Data Mismatch) และทุุกอย่างจะพังพินาศ
  • Stale Closures: เหมือน "รูปถ่ายของข้อมูล". เมื่อคุณสั่ง setTimeout มันเหมือนคุณถ่ายรูปกระดานดำเก็บไว้ แม้ว่าเชฟจะเดินมาแก้เลขบนกระดานทุุกวินาที แต่ในรูปถ่ายที่คุณถืออยู่ (Closure) เลขยังเป็นตัวเดิมเสมอ
  • useRef: เหมือน "กล่องใสที่ทุุกคนเห็นค่าข้างในตลอดเวลา". ไม่ว่าเวลาจะผ่านไปนานแค่ไหน ทุุกคนจะเห็นสิ่งที่อยู่ในกล่องนั้นเป็นค่าล่าสุดเสมอ

🚀 3. Execution Journey: มหากาพย์การคุม Hooks ให้อยู่หมัด

Senior จะเขียน Hooks โดยคำนึงถึง "ความสดใหม่" ของข้อมูลและ "ความประหยัด" ของทรัพยากร

🛠 Step-by-step:

  1. The Order Guard: ห้ามใส่ Hooks ใน if หรือ loop เด็ดขาด เพื่อรักษาลำดับของ Linked List ภายใน React
  2. The Functional Update: ใช้ท่า setCount(prev => prev + 1) เพื่อให้แน่ใจว่าเราได้ค่าล่าสุดเสมอโดยไม่ต้องพึ่งพิง Closure ภายนอก
  3. The Ref Bridge: ใช้ useRef เมื่อต้องการเข้าถึงค่าปัจจุบันภายใน Effect หรือ Timeout ที่มีระยะเวลานาน
  4. The Strategic Memo: ใช้ useMemo เฉพาะเมื่อมีการคำนวณที่หนักจริงๆ (เช่น Filter ข้อมูลหลักพัน) ไม่ใช่ใส่ทุุกจุดจน App หนักกว่าเดิม
HLJS TSX
// ✅ Best Practice: การแก้ปัญหา Stale Closure ด้วย Ref
function StableCounter() {
  const [count, setCount] = useState(0);
  const countRef = useRef(count);
  countRef.current = count; // 🛠 อัปเดต 'ความจริงล่าสุด' เสมอ

  const handleLog = () => {
    setTimeout(() => {
      console.log("ค่าที่แท้จริงตอนนี้คือ:", countRef.current); // 🛠 ได้ค่าล่าสุดแน่นอน
    }, 3000);
  };
  // ...
}

🪤 4. The Junior Trap: โรค "Optimization Overload"

จูเนียร์มักจะกลัว Re-render จนใส่ useCallback ครอบทุุกฟังก์ชัน:

HLJS TSX
// ❌ Junior Trap: ใส่ useCallback กับงานกระจอก
const handleClick = useCallback(() => {
    setOpen(false);
}, []);
// 🌋 พัง! เพราะการทำ useCallback มีค่าใช้จ่าย (CPU/Memory)
# ในการเปรียบเทียบ Dependency Array และจองพื้นที่หน่วยความจำ
# ซึ่งแพงกว่าการปล่อยให้ฟังก์ชันถูกสร้างใหม่เฉยๆ เสียอีก

ระวัง: ทุุกครั้งที่ใช้ Hooks เพื่อ Optimize คุณกำลังแลก 'ความเร็ว' กับ 'หน่วยความจำ' ✅ การแก้ไข: จงใช้ useCallback ก็ต่อเมื่อคุณต้องส่งฟังก์ชันนั้นไปเป็น Props ให้ลูกที่ทำ React.memo ไว้เท่านั้นครับ


⚖️ 5. The Why Matrix: useEffect vs useLayoutEffect

หัวข้อuseEffect (ทั่วไป)useLayoutEffect (ฉุกเฉิน)
จังหวะการรันรันหลังจากวาดหน้าจอเสร็จ🚨 รันก่อน Browser จะวาดหน้าจอ
UXอาจเห็นภาพกระตุก (Flicker)🚀 ลื่นไหล (ไม่มีรอยต่อ)
Performanceไม่บล็อกการวาดหน้าจอ🐢 บล็อกการวาด (เว็บอาจอืด)
เหมาะกับFetch ข้อมูล, ติดตาม Logคำนวณขนาด (Bounding Box) ของ UI

🎓 6. Senior Mindset Summary

การเป็น Senior คือการมองว่า "Hooks คือเครื่องมือในการจัดการสถานะ ไม่ใช่ของเล่นสำหรับปรับแต่งความเร็วไปวันๆ". โค้ดที่เรียบง่ายและทำงานถูกต้อง สำคัญกว่าโค้ดที่ดูฉลาดแต่แฝงไปด้วยบั๊กที่มองไม่เห็นครับ!

Share this note

Related notes

View all notes
mastery-frontend-react
Advanced

Advanced React Performance: ปรับแต่งเว็บให้ลื่นระดับ Senior

ปราบ Re-render ให้อยู่หมัดด้วยเทคนิคที่มากกว่าแค่การใช้ useMemo เจาะลึกความผิดพลาดที่จูเนียร์มักจะทำและการออกแบบ State ที่ประหยัดทรัพยากรที่สุด

January 30, 20262 min read
mastery-frontend-react
Advanced

React Rendering Mastery: เทคนิคเสกเว็บให้ลื่นระดับ 60 FPS

ไม่ได้มีแค่ useMemo! เจาะลึกกลไก Rendering Pipeline ของ Browser, เทคนิคใช้ GPU เร่งความเร็วการวาดหน้าจอ และการทำ Zero-Flicker UI ที่จะทำให้เว็บของคุณรู้สึกพรีเมียมที่สุด

January 30, 20262 min read
mastery-frontend-react
Advanced

React Under the Hood: Virtual DOM และ Reconciliation ทำงานยังไง?

ไม่ได้มีไว้ท่องจำ! เจาะลึกกลไกภายในของ React เข้าใจ Diffing Algorithm และ Fiber Architecture ว่าทำไม React ถึงเป็น Framework ที่ครองโลก พร้อมวิธีเขียนโค้ดให้สอดคล้องกับเครื่องยนต์หลัก

January 30, 20262 min read

© 2026 My Notes by Seereen