メインコンテンツへ移動

เนื้อหาภาษาไทย / タイ語のコンテンツ

システムガイド 内容確認済み

การจัดการ State ใน Component

บทความนี้กล่าวถึงความสำคัญของการจัดการ State ใน Component เพื่อให้ Component ทำงานได้อย่างถูกต้องและมีประสิทธิภาพ โดยแนะนำเครื่องมือหลักๆ อย่าง Context API และ...

การจัดการ State ใน Component

ในบทที่แล้ว เราได้เรียนรู้วิธีการสร้าง UI Component ที่สามารถนำไปใช้ซ้ำได้โดยใช้ Storybook ซึ่งช่วยให้เราพัฒนา Component ได้อย่างเป็นอิสระและสร้างเอกสารประกอบการใช้งานที่ชัดเจน แต่ Component ที่ดีไม่ได้มีแค่หน้าตาที่สวยงามเท่านั้น การจัดการ State อย่างมีประสิทธิภาพก็เป็นสิ่งสำคัญอย่างยิ่ง โดยเฉพาะอย่างยิ่งเมื่อ Component มีความซับซ้อนมากขึ้น

ในบทนี้ เราจะมาเจาะลึกเรื่อง State Management ใน Component กันครับ เราจะพูดถึง State คืออะไร ทำไมต้องจัดการ State และเครื่องมือต่างๆ ที่ช่วยให้เราจัดการ State ได้อย่างมีประสิทธิภาพ เช่น Context API และ Redux พร้อมทั้งพิจารณาว่าเครื่องมือไหนเหมาะสมกับสถานการณ์ใด

State คืออะไร?

State คือข้อมูลที่ Component เก็บไว้และใช้ในการ render UI Component นั้นๆ เมื่อ State เปลี่ยนแปลง Component จะทำการ re-render เพื่อแสดงผลลัพธ์ที่อัปเดต ตัวอย่างเช่น ปุ่มที่เปลี่ยนสีเมื่อถูกคลิก หรือ ช่องข้อความที่แสดงข้อความที่ผู้ใช้พิมพ์ State ทำให้ Component สามารถตอบสนองต่อการกระทำของผู้ใช้และเปลี่ยนแปลงตามสถานการณ์ต่างๆ ได้

ลองพิจารณา Component ง่ายๆ ที่แสดงจำนวนครั้งที่ปุ่มถูกคลิก:

import React, { useState } from 'react';

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

  const handleClick = () => {
    setCount(count + 1);
  };

  return (
    <button onClick={handleClick}>
      Clicked {count} times
    </button>
  );
}

export default ClickCounter;

ในตัวอย่างนี้ count คือ State ของ Component ClickCounter และ setCount คือฟังก์ชันที่ใช้ในการอัปเดต State เมื่อปุ่มถูกคลิก ฟังก์ชัน handleClick จะเรียก setCount เพื่อเพิ่มค่า count ขึ้นทีละ 1 ซึ่งจะทำให้ Component ทำการ re-render และแสดงจำนวนครั้งที่ถูกคลิกที่อัปเดตแล้ว

ทำไมต้องจัดการ State?

การจัดการ State เป็นสิ่งจำเป็นเพื่อให้ Component สามารถทำงานได้อย่างถูกต้องและมีประสิทธิภาพ โดยเฉพาะอย่างยิ่งเมื่อแอปพลิเคชันมีความซับซ้อนมากขึ้น การจัดการ State ที่ไม่ดีอาจนำไปสู่ปัญหาต่างๆ เช่น:

  • ความซับซ้อนที่เพิ่มขึ้น: เมื่อ Component มี State จำนวนมาก การจัดการ State โดยตรงอาจทำให้โค้ดซับซ้อนและยากต่อการบำรุงรักษา
  • การถ่ายทอด State ที่ยุ่งยาก: การส่ง State จาก Component หนึ่งไปยังอีก Component หนึ่ง (props drilling) อาจทำให้โค้ดอ่านยากและแก้ไขยาก
  • ปัญหาเรื่อง Performance: การอัปเดต State ที่ไม่จำเป็นอาจทำให้ Component ทำการ re-render บ่อยเกินไป ซึ่งส่งผลเสียต่อ Performance

ดังนั้น การใช้ State Management Library หรือเทคนิคที่เหมาะสมจึงเป็นสิ่งสำคัญในการจัดการ State อย่างมีประสิทธิภาพและลดปัญหาที่อาจเกิดขึ้น

Context API คืออะไร?

Context API เป็นเครื่องมือที่มาพร้อมกับ React ช่วยให้เราสามารถส่งข้อมูล (เช่น State) ไปยัง Component ใดๆ ใน Component Tree โดยไม่ต้องส่งผ่าน props (props drilling) เหมาะสำหรับข้อมูลที่ Component หลายตัวต้องการใช้ร่วมกัน เช่น ข้อมูลผู้ใช้ที่ Login หรือ Theme ของแอปพลิเคชัน

ข้อดีของ Context API:

  • ใช้งานง่ายและไม่ต้องติดตั้ง Library เพิ่มเติม
  • เหมาะสำหรับข้อมูลที่ใช้ร่วมกันในหลาย Component
  • ช่วยลดความซับซ้อนของการถ่ายทอด State

ข้อเสียของ Context API:

  • ไม่เหมาะสำหรับ State ที่มีการเปลี่ยนแปลงบ่อย
  • อาจทำให้ Component ทำการ re-render บ่อยเกินไปหาก Context Value เปลี่ยนแปลง
  • ไม่เหมาะสำหรับ State ที่มีความซับซ้อนและต้องการการจัดการที่ละเอียด

ตัวอย่างการใช้งาน Context API:

import React, { createContext, useState, useContext } from 'react';

// สร้าง Context
const ThemeContext = createContext();

// Provider Component
function ThemeProvider({ children }) {
  const [theme, setTheme] = useState('light');

  const toggleTheme = () => {
    setTheme(theme === 'light' ? 'dark' : 'light');
  };

  return (
    <ThemeContext.Provider value={{ theme, toggleTheme }}>
      {children}
    </ThemeContext.Provider>
  );
}

// Consumer Component
function ThemedComponent() {
  const { theme, toggleTheme } = useContext(ThemeContext);

  return (
    <div style={{ backgroundColor: theme === 'light' ? 'white' : 'black', color: theme === 'light' ? 'black' : 'white' }}>
      <p>Current Theme: {theme}</p>
      <button onClick={toggleTheme}>Toggle Theme</button>
    </div>
  );
}

// การใช้งาน
function App() {
  return (
    <ThemeProvider>
      <ThemedComponent />
    </ThemeProvider>
  );
}

export default App;

ในตัวอย่างนี้ เราสร้าง ThemeContext และ ThemeProvider ซึ่งเป็น Context Provider ที่เก็บ State ของ Theme และฟังก์ชัน toggleTheme จากนั้นเราใช้ useContext Hook ใน ThemedComponent เพื่อเข้าถึงค่าจาก Context และใช้ในการ render UI Component

Redux คืออะไร?

Redux เป็น State Management Library ที่ได้รับความนิยมอย่างมาก ช่วยให้เราจัดการ State ของแอปพลิเคชันได้อย่างเป็นระบบและ predictable โดยมีหลักการสำคัญ 3 ข้อ:

  1. Single Source of Truth: State ทั้งหมดของแอปพลิเคชันถูกเก็บไว้ใน Store เดียว
  2. State is Read-Only: State สามารถเปลี่ยนแปลงได้ผ่าน Action เท่านั้น
  3. Changes are Made with Pure Functions: Reducer เป็นฟังก์ชันที่รับ State ปัจจุบันและ Action และคืนค่า State ใหม่

ข้อดีของ Redux:

  • Predictable State Management
  • Centralized State
  • DevTools ที่มีประสิทธิภาพ
  • Community ขนาดใหญ่และ Library เสริมมากมาย

ข้อเสียของ Redux:

  • Boilerplate Code จำนวนมาก
  • Learning Curve ที่สูงกว่า Context API
  • อาจ Overkill สำหรับแอปพลิเคชันขนาดเล็ก

ตัวอย่างการใช้งาน Redux:

import React from 'react';
import { createStore } from 'redux';
import { Provider, connect } from 'react-redux';

// Reducer
const counterReducer = (state = { count: 0 }, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return { count: state.count + 1 };
    case 'DECREMENT':
      return { count: state.count - 1 };
    default:
      return state;
  }
};

// Store
const store = createStore(counterReducer);

// Component
function Counter({ count, increment, decrement }) {
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
      <button onClick={decrement}>Decrement</button>
    </div>
  );
}

// Map State to Props
const mapStateToProps = (state) => ({
  count: state.count,
});

// Map Dispatch to Props
const mapDispatchToProps = (dispatch) => ({
  increment: () => dispatch({ type: 'INCREMENT' }),
  decrement: () => dispatch({ type: 'DECREMENT' }),
});

// Connect Component to Redux Store
const ConnectedCounter = connect(mapStateToProps, mapDispatchToProps)(Counter);

// การใช้งาน
function App() {
  return (
    <Provider store={store}>
      <ConnectedCounter />
    </Provider>
  );
}

export default App;

ในตัวอย่างนี้ เราสร้าง Reducer (counterReducer), Store (store) และ Component (Counter) จากนั้นเราใช้ connect function จาก react-redux เพื่อเชื่อมต่อ Component กับ Redux Store และส่ง State และ Action เป็น Props ให้กับ Component

การเลือกใช้ State Management Library

การเลือกใช้ State Management Library ที่เหมาะสมขึ้นอยู่กับขนาดและความซับซ้อนของแอปพลิเคชัน:

  • Context API: เหมาะสำหรับแอปพลิเคชันขนาดเล็กถึงกลาง ที่ต้องการจัดการ State ที่ใช้ร่วมกันในหลาย Component โดยไม่ต้องพึ่งพา Library ภายนอก
  • Redux: เหมาะสำหรับแอปพลิเคชันขนาดใหญ่และซับซ้อน ที่ต้องการจัดการ State อย่างเป็นระบบและ predictable มีทีมงานขนาดใหญ่ที่ต้องการเครื่องมือที่สามารถ debug และ scale ได้ง่าย

นอกจาก Context API และ Redux แล้ว ยังมี State Management Library อื่นๆ อีกมากมาย เช่น Zustand, Recoil, Jotai ซึ่งแต่ละ Library ก็มีข้อดีข้อเสียแตกต่างกันไป การเลือกใช้ Library ที่เหมาะสมควรพิจารณาจากความต้องการและข้อจำกัดของโปรเจกต์

สรุป:

การจัดการ State เป็นสิ่งสำคัญในการพัฒนา UI Component ที่สามารถทำงานได้อย่างถูกต้องและมีประสิทธิภาพ Context API และ Redux เป็นเครื่องมือที่ช่วยให้เราจัดการ State ได้อย่างมีประสิทธิภาพ แต่การเลือกใช้เครื่องมือที่เหมาะสมขึ้นอยู่กับขนาดและความซับซ้อนของแอปพลิเคชัน

ในบทต่อไป เราจะพูดถึงการสื่อสารระหว่าง Component ซึ่งเป็นอีกหนึ่งหัวข้อที่สำคัญในการสร้าง UI Component ที่นำกลับมาใช้ใหม่ได้ครับ

Office.in.th Custom Service

この構成をもとにシステムを開発・カスタマイズしたいですか?

Office.in.th は、エンタープライズ Web アプリケーション、API 連携、官民の業務管理システムの設計・開発を承り、長期的なサポートも提供します。

ソフトウェア開発サービスを見る