398 words
2 minutes
React | State

อ่านเกี่ยวกับ React Basic

State คืออะไรใน React#

  • อธิบายว่า State ใน React คือข้อมูลที่อยู่ภายใน Component และสามารถเปลี่ยนแปลงได้ตลอดอายุการใช้งานของ Component นั้น
  • ความแตกต่างระหว่าง Props และ State (Props ส่งค่าจาก Parent Component แต่ State เป็นข้อมูลภายใน Component)

วิธีการใช้ State ด้วย useState Hook#

  • แนะนำการใช้ useState ซึ่งเป็น Hook สำหรับจัดการ State ใน Functional Components

  • ตัวอย่างการประกาศและใช้งาน useState:

import { useState } from 'react';

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

  return (
    <div>
      <p>คุณคลิก {count} ครั้ง</p>
      <button onClick={() => setCount(count + 1)}>
        คลิกเพิ่ม
      </button>
    </div>
  );
}
  • อธิบายโครงสร้าง :

    • useState(0) คือการกำหนดค่าเริ่มต้นเป็น 0
    • count คือตัวแปรที่เก็บค่า State
    • setCount คือฟังก์ชันสำหรับอัปเดตค่า State
    • เมื่อกดปุ่ม ค่าของ count จะถูกอัปเดต และ Component จะทำการ re-render

การจัดการ State หลายค่า#

การใช้หลายค่าใน useState ใน Component เดียว

function Form() {
  const [name, setName] = useState('');
  const [age, setAge] = useState(0);

  return (
    <div>
      <input 
        type="text" 
        placeholder="ชื่อของคุณ" 
        value={name} 
        onChange={(e) => setName(e.target.value)} 
      />
      <input 
        type="number" 
        placeholder="อายุของคุณ" 
        value={age} 
        onChange={(e) => setAge(e.target.value)} 
      />
      <p>ชื่อ: {name}, อายุ: {age}</p>
    </div>
  );
}
  • อธิบายว่าเราสามารถใช้ useState หลายครั้งสำหรับค่าที่ต่างกัน และ React จะ re-render เมื่อค่าถูกอัปเดต

การอัปเดต State อย่างถูกต้อง#

  • อธิบายว่าการอัปเดต State ใน React จะไม่เกิดขึ้นทันที แต่ React จะเก็บการเปลี่ยนแปลงไว้และอัปเดตเมื่อ Component ถูก re-render
  • แนะนำการใช้ ฟังก์ชันในการอัปเดต State:
setCount((prevCount) => prevCount + 1);
  • ฟังก์ชันนี้จะรับค่า State ปัจจุบัน (prevCount) และอัปเดต State ใหม่โดยใช้ค่าก่อนหน้า เป็นการป้องกันปัญหาเมื่อมีการอัปเดต State หลายครั้งในเวลาเดียวกัน

เปรียบเทียบการใช้ State 2 แบบนี้ต่างกันอย่างไร ?#

setCount((prevCount) => prevCount + 1); // แบบที่ 1
setCount(count + 1)  // แบบที่ 2 
TIP
  • หากเราสร้างปุ่มแล้วมี Function ดังต่อไปนี้ เมื่อกดปุ่มคิดว่า Output จะออกมาในลักษณะไหน ?
//แบบที่ 1
const [count, setCount] = useState(0)
setCount((prevCount) => prevCount + 1)
setCount((prevCount) => prevCount + 1)
setCount((prevCount) => prevCount + 1)
// Output 3 
// ค่าที่ได้จะเพิ่มขึ้นครั้งละ 3 เมื่อมีการกดปุ่ม เพราะเราใช้ prevCount ซึ่งเป็นค่า State ปัจจุบัน 
  • จากที่เข้าใจคือจะทำงานทีละ Function แล้วเอาค่าที่ได้ไปใช้ใน Function ถัดไปคร้าบ
//แบบที่ 2
const [count, setCount] = useState(0)
setCount(count + 1)
setCount(count + 1)
setCount(count + 1)
// Output 1 
// ค่าที่ได้จะเพิ่มขึ้นเพียง 1 เมื่อมีการกดปุ่ม เพราะเราใช้ count ซึ่งเป็นค่า State ที่ไม่ได้อัปเดตในการคำนวณค่าใหม่
  • จากข้างต้นถ้าหากเราเอามาเขียนแบบนี้ แบบที่ 1 จะเป็นการอัปเดต State อย่างถูกต้อง
  • แบบที่ 2 จะไม่ใช่การอัปเดต State อย่างถูกต้อง
  • เพราะว่าเราไม่ได้ใช้ค่า State ปัจจุบันในการอัปเดต State แต่เราใช้ค่า State เก่าไปแทน ซึ่งอาจจะเกิดปัญหาได้ในกรณีที่มีการอัปเดต State หลายครั้งในเวลาเดียวกัน และค่า State ที่เก่าอาจจะไม่ใช่ค่าที่ถูกต้องแล้ว

การจัดการ State เชิงซ้อน (เช่น State ที่เป็น Object หรือ Array)#

  • การจัดการ State ที่เป็น Object:
// แบบที่ 1 
const [user, setUser] = useState({ name: '', age: 0 });

function updateUser(name, age) {
  setUser((prevUser) => ({ ...prevUser, name, age }));
}
  • อธิบายว่าการอัปเดต State ที่เป็น Object ควรใช้ spread operator (…prevUser) เพื่อไม่ทำให้ค่าที่ไม่ได้เปลี่ยนแปลงหายไป การจัดการ State ที่เป็น Array:
const [items, setItems] = useState([]);

function addItem(newItem) {
  setItems((prevItems) => [...prevItems, newItem]);
}

การใช้ State ในฟอร์มและการควบคุมการรับข้อมูล#

  • การจัดการ input fields ด้วย State (controlled components)
  • ตัวอย่างการผูก State กับฟอร์มเพื่อรับข้อมูลจากผู้ใช้
const [inputValue, setInputValue] = useState('');

return (
  <input 
    type="text" 
    value={inputValue} 
    onChange={(e) => setInputValue(e.target.value)} 
  />
);

การทำงานร่วมกับ useEffect เพื่อจัดการ side effects#

  • เมื่อมีการเปลี่ยนแปลงของ State อาจจะต้องทำงานบางอย่าง เช่น ดึงข้อมูลจาก API
  • อธิบายการใช้ useEffect กับ State เพื่อทำงานร่วมกัน เช่น การดึงข้อมูลเมื่อ State เปลี่ยนแปลง
useEffect(() => {
  // ทำงานเมื่อ state เปลี่ยนแปลง
  fetchData();
}, [state]);

สรุปข้อควรระวังในการใช้ State#

  • อย่าแก้ไข State โดยตรง (เช่น state.push() หรือstate = ...)
  • ใช้ฟังก์ชัน setState เสมอในการอัปเดตค่า
  • ระวังการอัปเดต State หลายครั้งในเวลาสั้นๆ ที่อาจทำให้เกิดปัญหา
React | State
https://astro-blog.vercel.app/posts/react/react-state/
Author
MartinCats
Published at
2024-11-25