ทำความรู้จักกับ useState และ useEffect ใน React JS กัน

Faruslan Waming
Lotus’s IT
Published in
4 min readJan 31, 2024

สวัสดีครับทุกคนกลับมาเจอกันอีกแล้ว … สำหรับบทความนี้ ผมจะมาพูดถึง hooks ที่ใช้ใน React JS ที่ผมได้ใช้งานอยู่นั้นก็คือ useState และ useEffect ว่าคืออะไร และ มีการใช้งานอย่างไร พร้อมกับให้ตัวอย่างโค้ดที่จะช่วยให้คุณทำความเข้าใจได้ง่ายภายในระยะเวลา 5 นาที ไปเริ่มกันเลยยย

useState คืออะไร

Image reference: React useState Hook in Action: What You Need to Know (alexdevero.com)

useState ใน React JS มีความหมายว่า เป็นฟังก์ชันที่ใช้ในการสร้าง state variable ใน functional component ของ React State variable นี้ซึ่งจะถูกใช้เพื่อเก็บค่าที่อาจเปลี่ยนแปลงได้ขณะทำงานของ component และทำให้ React ทราบว่าเมื่อมี state เปลี่ยนแปลง React จะต้องรีเรนเดอร์ component ใหม่ทุกครั้ง

ความหมายของ useState สามารถแบ่งออกเป็นส่วนย่อย ๆ ได้ดังนี้

  1. สร้าง State Variable : useState จะทำหน้าที่สร้าง state variable และกำหนดค่าเริ่มต้นให้กับ state นั้น ๆ ในรูปแบบ [state, setState] โดย state คือค่าปัจจุบันของ state และ setState เป็นฟังก์ชันที่ใช้ในการเปลี่ยนแปลงค่าของ state
  2. การใช้ State Variable : เราจะใช้ state variable เพื่อเก็บข้อมูลที่อาจจะมีการเปลี่ยนแปลงใน component นั้น ๆ โดยจะใช้ค่าที่ถูกเก็บไว้ใน state และเราสามารถอ่านค่านี้ได้ตลอดระยะเวลาทำงานของ component นั้นๆ
  3. การเปลี่ยนแปลง State : เมื่อต้องการเปลี่ยนแปลงค่าของ state variable ให้เราใช้ฟังก์ชัน setState ที่ถูกสร้างขึ้นโดย useState โดยการเรียกใช้ setState นี้จะทำให้ React รู้ว่า state ได้เปลี่ยนแปลงและต้องทำการรีเรนเดอร์ component ใหม่ทุกครั้ง

รูปแบบของ useState มีดังนี้

const [state, setState] = useState(initialState);
  • state : เป็นตัวแปรที่ใช้ในการเก็บค่าของ state นั้น ๆ ใน component เริ่มต้นด้วยค่า initialState
  • setState : เป็นฟังก์ชันที่ใช้ในการเปลี่ยนแปลงค่าของ state เมื่อ setState ถูกเรียก React จะทราบว่า state ได้เปลี่ยนแปลงและต้องทำการรีเรนเดอร์ component นั้นเอง
  • initialState : คือค่าเริ่มต้นของ state ในตอนเริ่มต้น state จะมีค่าเท่ากับ initialState

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

import React, { useState } from 'react';

function ExampleComponent() {
// สร้าง state variable count และ setCount เริ่มต้นด้วยค่า 0
const [count, setCount] = useState(0);

// สร้าง state variable text และ setText เริ่มต้นด้วยค่าว่าง
const [text, setText] = useState('');

// ฟังก์ชันที่ใช้ในการเพิ่มค่าตัวแปร count
const incrementCount = () => {
setCount(count + 1);
};

// ฟังก์ชันที่ใช้ในการเปลี่ยนแปลงค่าตัวแปร text
const handleTextChange = (event) => {
setText(event.target.value);
};

return (
<div>
<p>ค่าปัจจุบันของตัวแปร count: {count}</p>
<button onClick={incrementCount}>
เพิ่มค่า
</button>

<p>ค่าปัจจุบันของตัวแปร text: {text}</p>
<input type="text" value={text} onChange={handleTextChange} />
</div>
);
}

export default ExampleComponent;

อธิบายโค้ดในตัวอย่างข้างต้น

  • เราจะสร้าง state variable count และ setCount เริ่มต้นด้วยค่า 0 โดยใช้ useState(0) และสร้าง state variable text และ setText เริ่มต้นด้วยค่าว่าง โดยใช้ useState(‘’)
  • สร้างฟังก์ชัน incrementCount เพื่อใช้ในการเพิ่มค่าของ count เมื่อปุ่มถูกคลิก
  • สร้างฟังก์ชัน handleTextChange เพื่อใช้ในการเปลี่ยนแปลงค่าของ text เมื่อมีการพิมพ์ใน input element
  • แสดงค่าปัจจุบันของ count และ text ใน JSX และให้ผู้ใช้กรอกข้อความใน input element ได้

เมื่อ component ถูกเรียกใช้ React จะจัดการเก็บและติดตามการเปลี่ยนแปลงของ count และ text และทำให้ component รีเรนเดอร์เมื่อมีการเปลี่ยนแปลง

สิ่งที่สำคัญที่จะต้องทราบเกี่ยวกับ useState คือว่า state ใน React ถูกจัดเก็บแบบอัปเดตแบบไม่แบ่งแยก (unified state) ซึ่งหมายความว่าการเรียก setStare จะรีเรนเดอร์ component อีกครั้ง และ React จะจัดการในการอัพเดทและ render component ให้เป็นไปตาม state ที่อัพเดทแล้ว

useEffect คืออะไร

Image reference: React useEffect Hook Made Simple (alexdevero.com)

useEffect เป็นฟังก์ชันใน React ที่ใช้ในการจัดการผลกระทบของ side effects (ผลกระทบที่เกิดจากการทำงานข้างเคียง เช่น เรียก API หรือ การทำงานกับ DOM) ใน functional components Side effects มักจะเกี่ยวข้องกับการติดต่อกับภายนอก เช่น การโหลดข้อมูลจากเซิร์ฟเวอร์ หรือ การอัปเดต DOM หรือ การตั้งค่าการทำงานที่ไม่ได้เกี่ยวกับการเรนเดอร์

การใช้ useEffect จะช่วยให้คุณสามารถทำงานข้ามเครื่องในระหว่าง lifecycle ของ component ได้โดย useEffect จะถูกเรียกหลังจาก component ถูก render และหลังจากทุกครั้งที่ state หรือ props มีการเปลี่ยนแปลงค่า

รูปแบบของ useEffect มีดังนี้

useEffect(() => {
// โค้ดที่ต้องการให้ทำงานเมื่อเกิด side effect
// เช่น การเรียก API, อัปเดต DOM, หรือตั้งค่าตัวแปรที่ไม่ใช่ state

return () => {
// โค้ดที่ต้องการให้ทำงานเมื่อ component ถูกทำลาย (clean-up)
// เช่น การยกเลิก subscription, การลบ event listener
};
}, [dependencies]);
  • Function : เป็นฟังก์ชันที่จะทำงานเมื่อ component ถูกเรนเดอร์ หรือเมื่อมีการเปลี่ยนแปลงใน dependencies (อาร์เรย์ที่ถูกส่งเข้าไป)
  • Dependencies (optional) : เป็นอาร์เรย์ของขั้นตอนที่ถ้ามีการเปลี่ยนแปลงในขั้นตอนใดขั้นตอนหนึ่ง ฟังก์ชันที่ถูกส่งเข้าไปใน useEffect จะถูกเรียกใหม่
  • Clean-up Function : การ return ฟังก์ชันจาก useEffect จะทำให้ React ทราบว่าเมื่อ component ถูกทำลาย ฟังก์ชันนี้ควรถูกเรียก (clean-up) เป็นที่นิยมในการทำลาย subscription, event listener, หรือทำ clean-up อื่น ๆ

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

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

function ExampleComponent() {
const [data, setData] = useState(null);

// useEffect ที่ถูกใช้เมื่อ component ถูกเรนเดอร์
useEffect(() => {
// โค้ดที่จะทำงานเมื่อ component ถูกเรนเดอร์
fetchData();

// ฟังก์ชัน clean-up
return () => {
// โค้ดที่จะทำงานเมื่อ component ถูกทำลาย
// เช่น การยกเลิก subscription, การลบ event listener
console.log('Component is unmounted.');
};
}, []); // [] ว่าง หมายความว่า จะไม่มี dependencies อยู่ใน useEffect

const fetchData = async () => {
try {
const response = await fetch('https://api.example.com/data');
const result = await response.json();
setData(result);
} catch (error) {
console.error('Error fetching data:', error);
}
};

return (
<div>
{/* แสดงข้อมูลที่ได้จาก API */}
{data && (
<ul>
{data.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
)}
</div>
);
}

export default ExampleComponent;

อธิบายโค้ดในตัวอย่างข้างต้น

  • useEffect จะถูกใช้เพื่อโหลดข้อมูลจาก API เมื่อ component ถูกเรนเดอร์
  • Clean-up function จะถูกใช้เพื่อบอกให้ React ทราบว่าเมื่อ component ถูกทำลาย (unmounted) ให้ทำ clean-up เช่น การยกเลิก subscription, การลบ event listener
  • Dependencies จะถูกตั้งค่าเป็น [] ทำให้ useEffect ทำงานเพียงครั้งเดียวเมื่อ component ถูกเรนเดอร์ (componentDidMount)
  • fetchData จะถูกเรียกเพื่อดึงข้อมูลจาก API และอัปเดต state data ใน component

ตัวอย่างการใช้งานร่วมกันระหว่าง useState กับ useEffect

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

function ExampleComponent() {
// ใช้ useState เพื่อทำการสร้าง state สำหรับเก็บค่าตัวแปร count
const [count, setCount] = useState(0);

// ใช้ useState เพื่อทำการสร้าง state สำหรับเก็บข้อมูลที่ได้จาก API
const [data, setData] = useState(null);

// ใช้ useEffect เพื่อทำ side effect เมื่อค่าตัวแปร count มีการเปลี่ยนแปลง
useEffect(() => {
// ฟังก์ชัน fetchData ที่ใช้ใน useEffect
const fetchData = async () => {
try {
// ทำการเรียก API ด้วย fetch
const response = await fetch(`https://api.example.com/data?count=${count}`);

// ทำการแปลง response เป็น JSON
const result = await response.json();

// อัพเดท state data จากข้อมูลที่ได้มาจาก response
setData(result);
} catch (error) {
// จัดการข้อผิดพลาด
console.error('Error fetching data:', error);
}
};

// เรียกใช้งาน fetchData เมื่อค่าตัวแปร count มีการเปลี่ยนแปลง
fetchData();

// Cleanup function ที่จะถูกเรียกเมื่อ component ถูก unmount
return () => {
// ทำการคืนการทำงานที่ต้องการ (cleanup)
console.log('Component unmounted');
};
}, [count]); // Dependencies ถูกกำหนดเป็น [count]

return (
<div>
{/* แสดงค่า count และปุ่มที่เมื่อคลิกจะเพิ่มค่า count */}
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>

{/* แสดงข้อมูลที่ได้จาก API */}
{data && <p>Data: {data}</p>}
</div>
);
}

export default ExampleComponent;

อธิบายโค้ดในตัวอย่างข้างต้น

  • เราจะใช้ useState เพื่อสร้าง state count และ data
  • เราใช้ useEffect เพื่อดึงข้อมูลจาก API เมื่อค่า count เปลี่ยน
  • Cleanup function จะถูกใช้เพื่อทำคืนการทำงานเมื่อ component ถูก unmount เพื่อป้องกัน side effects ที่ไม่จำเป็น
  • เมื่อปุ่มถูกคลิก เราจะเรียก setCount เพื่อเปลี่ยนค่าตัวแปร count และทำให้ useEffect ทำงานอีกครั้ง

สรุป

จบไปแล้วครับ สำหรับบทความที่กล่าวมาข้างต้น เกี่ยวกับ hooks ที่ผมได้ใช้งานใน Project React JS สำหรับตัว useState และ useEffect เป็นยังไงกันบ้างครับ มันใช้งานง่ายใช่ไหมน้า สำหรับท่านใดที่ต้องการจะศึกษาเพิ่มเติมเกี่ยวกับ hooks ใน React JS สามารถเข้าไปอ่านเพิ่มเติมได้ที่ Link : https://react.dev/reference/react/hooks

… สุดท้ายท้ายสุด บทความนี้อาจไม่ได้ดีไปกว่าบทความอื่นที่เขียนเกี่ยวกับ useState และ useEffect ผมหวังว่าทุกคนที่ได้เข้ามาอ่านบทความนี้จะได้รับประโยชน์ไม่มากก็น้อยนะครับ ถ้ามีข้อผิดพลาด หรือ ตกหล่นในส่วนไหน ก็ขออภัยมา ณ ที่นี้ด้วยครับ เจอกันใหม่ บทความหน้าครับ ขอบคุณครับ …

--

--