Back to notes
mastery-frontend-react
Featured

Modern Data Fetching: ทิ้ง Redux แล้วมาซบอก React Query

รู้จัก TanStack Query (React Query) อาวุธลับในการจัดการ Server State ที่จะทำให้โค้ด data fetching หายไป 90% พร้อมเทคนิคการจัดการ Cache และ Invalidation ขั้นเซียน

January 30, 20262 min read readNNexis by Seereen

🛑 1. The Problem First: "โค้ดที่เต็มไปด้วย if-loading และ data-stale"

ลองนึกถึงวันที่คุณต้องดึงข้อมูลรายการสินค้ามาโชว์:

HLJS TSX
// ❌ Naive Approach: เขียน Fetch แบบดิบๆ (เหนื่อยทุุก API)
const [data, setData] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);

useEffect(() => {
    fetch('/api/products')
      .then(res => res.json())
      .then(setData)
      .catch(setError)
      .finally(() => setIsLoading(false));
}, []);
// 🌋 พัง! คุณต้องเขียน boilerplate นี้ซ้ำๆ 100 รอบในทุุกหน้า
# และที่แย่กว่านั้นคือถ้า User สลับ Tab ไปมา ข้อมูลในหน้าอาจจะ 'บูด' (Stale)
# ไปแล้วโดยที่คุณไม่มีระบบดึงใหม่ให้อัตโนมัติเลยครับ

ปัญหา: การดึงข้อมูลไม่ใช่แค่เรื่องของการยิง Request แต่คือเรื่องของการจัดการ State ถังกลาง (Cache), การรับมือกับ Network ที่ไม่นิ่ง และการทำให้ข้อมูล "สดใหม่" (Fresh) อยู่เสมอโดยไม่รบกวน User ครับ


💡 2. Real-Life Analogy: ห้องสมุดอัจฉริยะ

  • Standard Fetch (useEffect): เหมือนคุณเดินไปที่เคาน์เตอร์บรรณารักษ์ทุุกครั้งเพื่อถามหาหนังสือเล่มเดิม บรรณารักษ์ต้องเดินไปหยิบจากชั้นหลังสุดทุุกรอบ (เสียเวลา)
  • React Query (Caching): เหมือน "โต๊ะพักหนังสือ". ถ้ามีคนเคยขอดูหนังสือเล่มนี้เมื่อ 1 นาทีที่แล้ว บรรณารักษ์จะหยิบจากโต๊ะข้างหน้าให้ทันที (เร็วมาก) และถ้าหนังสือเล่มนั้นถูกแก้ไข (Mutation) บรรณารักษ์จะรีบเอาไปเปลี่ยนบนชั้นพ้นที (Invalidation)
  • Stale-While-Revalidate: เหมือนพนักงานบอกคุณว่า "นี่คือข้อมูลล่าสุดที่เรามีนะดูไปก่อน เดี๋ยวผมวิ่งไปเช็คที่คลังอีกทีว่ามีการอัปเดตไหม ถ้ามีเดี๋ยวผมแก้บนหน้ากระดาษให้ทันที"

🚀 3. Execution Journey: มหากาพย์การใช้เครื่องทุ่นแรง

Senior จะไม่เขียนระบบ Fetching เอง แต่จะใช้ระบบที่ "คิดมาเผื่อทุุกสภาวะ" แล้ว

🛠 Step-by-step:

  1. The Query Key: กำหนด 'ชื่อ' ให้กับข้อมูลทุุกชุด เพื่อให้ React Query รู้ว่าต้องดึงจาก Cache ตัวไหน
  2. The Fetcher Wrapper: สร้างฟังก์ชันดึงข้อมูลที่เป็นอิสระ (Pure Function) เพื่อให้ง่ายต่อการทดสอบ (Testing)
  3. The Simple Hook: เรียกใช้ useQuery พร้อมจัดการสถานะ isLoading และ error ในที่เดียว
  4. The Smart Invalidator: ใช้ mutation.onSuccess เพื่อสั่งให้ข้อมูลหน้าอื่นอัปเดตตามทันทีเมื่อเราแก้ไขอะไรบางอย่าง
HLJS TSX
// ✅ Best Practice: การใช้ React Query ขั้นพื้นฐาน (แต่ทรงพลัง)
const { data, isLoading } = useQuery({
  queryKey: ["products"], // 🛠 ชื่อของ Cache
  queryFn: () => axios.get("/api/products").then((res) => res.data),
  staleTime: 1000 * 60 * 5, // 🛠 ให้ข้อมูลสดเป็นเวลา 5 นาที ไม่ต้องยิงใหม่ซ้ำๆ
});

🪤 4. The Junior Trap: โรค "Manual Synchronizing"

จูเนียร์มักจะพยายามอัปเดต State เองหลังจากที่ POST ข้อมูลสำเร็จ:

HLJS TSX
// ❌ Junior Trap: แก้ไข State ในเครื่องแบบเดาๆ
const handleUpdate = async () => {
    await updateProduct(id, newData);
    // 🌋 พัง! จูเนียร์จะเขียน:
    setProducts(products.map(p => p.id === id ? newData : p));
    # การทำแบบนี้เสี่ยงมากเพราะ 'ความจริง' ในฐานข้อมูลอาจจะเปลี่ยนไปแล้ว
    # หรือมี Logic หลังบ้านที่เราไม่ได้ทำเลียนแบบไว้ใน Client

ระวัง: อย่าพยายามเป็นฐานข้อมูลจำลองใน Client ✅ การแก้ไข: จงใช้ queryClient.invalidateQueries เพื่อสั่งให้ React Query ไปดึง 'ความจริง' มาจาก Server ใหม่ทุุกครั้งหลังการแก้ไขครับ


⚖️ 5. The Why Matrix: Redux (Server State) vs React Query

หัวข้อRedux (แบบเก่า)React Query (Senior)
Boilerplate🌋 มหาศาล (Action/Reducer)⚡⚡ น้อยมาก (1 Hook)
Cachingต้องเขียนเองทุุกบรรทัด🚀 ทำมาให้ฟรีและฉลาดมาก
Auto-updateไม่มี🚀 รันอัตโนมัติเมื่อ Window Focus
ความรู้สึกของ Devเหนื่อยและบั๊กเยอะ😍 สนุกและระบบนิ่งกว่าเยอะ

🎓 6. Senior Mindset Summary

การเป็น Senior คือการมองว่า "เราควรเอาเวลาไปแก้ปัญหาทางธุรกิจ ไม่ใช่เอาเวลามานั่งเขียน if-loading ซ้ำๆ 100 รอบ". React Query ไม่ใช่แค่ Library แต่มันคือการเปลี่ยน 'ภาระ' ให้กลายเป็น 'ระบบ' ที่จะทำให้แอปของคุณนิ่งและเร็วขึ้นอย่างเห็นได้ชัดครับ!

Share this note

Related notes

View all notes
mastery-frontend-react
Basic

State Management Philosophy: จริงๆ แล้วคุณอาจไม่ต้องใช้ Redux/Zustand

พอกันทีกับการเก็บทุุกอย่างไว้ใน Store กลาง! เจาะลึกแนวคิดการใช้ URL เป็นแหล่งความจริงสูงสุด (Single Source of Truth) และการแยกแยะระหว่าง Server State กับ Client State อย่างมืออาชีพ

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

Scalable React Architecture: จัดโครงสร้าง Folder ยังไงไม่ให้โปรเจกต์ระเบิด

เลิกกองทุุกอย่างไว้ที่ components/! เจาะลึกโครงสร้างแบบ Feature-based, เทคนิค Colocation และการออกแบบระบบให้พร้อมเติบโตได้เป็นเวลา 10 ปีโดยไม่เป็นภาระของลูกหลาน

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

React Testing Library: เลิก Test รายละเอียดโค้ด แล้วมา Test ความรู้สึก User

เขียน Test ให้เหมือนคนใช้งานจริง! เจาะลึกปรัชญาการเขียน Test ที่ทนทานต่อการ Refactor เลิกหา Component ด้วย ClassName และเปลี่ยนมาใช้ระบบ Accessibility Role แทน

January 30, 20263 min read

© 2026 My Notes by Seereen