ซิงโครไนซ์คอมโพเนนต์ของคุณกับโลกภายนอกด้วย useEffect โดยเชี่ยวชาญเรื่อง dependencies และ cleanup
เปิดบทเรียนนี้ใน Kodokonคอมโพเนนต์ React คำนวณ JSX จาก props และ state สิ่งใดที่อยู่นอกขอบเขตนั้น - การเปลี่ยน title ของเอกสาร การเริ่มตัวจับเวลา การสมัครรับอีเวนต์ของเบราว์เซอร์ - ถือเป็น ผลข้างเคียง (side effect) useEffect รันโค้ดนั้น หลังจาก การเรนเดอร์ โดยไม่บล็อกการแสดงผล และซิงโครไนซ์ใหม่เมื่อค่าบางค่าเปลี่ยน
import { useEffect } from "react";
function CartTitle({ count }) {
useEffect(() => {
document.title = `Cart (${count})`;
}, [count]);
return <p>Items: {count}</p>;
}อาร์เรย์ dependencies ควบคุมว่าเอฟเฟกต์จะรันบ่อยแค่ไหน [count]: เอฟเฟกต์รันใหม่หลังทุกการเรนเดอร์ที่ count เปลี่ยน []: เอฟเฟกต์รันเพียงครั้งเดียว หลังการเรนเดอร์ครั้งแรก ไม่มีอาร์เรย์: เอฟเฟกต์รันใหม่หลัง ทุก การเรนเดอร์ ซึ่งมักไม่ใช่สิ่งที่คุณต้องการ กฎทอง: ทุกค่าของคอมโพเนนต์ที่ใช้ภายในเอฟเฟกต์ต้องปรากฏในอาร์เรย์
import { useEffect, useState } from "react";
function Timer() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const id = setInterval(() => {
setSeconds((s) => s + 1);
}, 1000);
return () => clearInterval(id);
}, []);
return <p>Elapsed: {seconds} s</p>;
}ฟังก์ชันที่เอฟเฟกต์คืนค่ากลับมาคือฟังก์ชัน cleanup React เรียกมันก่อนการรันเอฟเฟกต์รอบใหม่ทุกครั้ง แล้วเรียกอีกครั้งหนึ่งเป็นครั้งสุดท้ายเมื่อคอมโพเนนต์ถูกถอด (unmount) มันคือสิ่งที่ป้องกันการรั่วไหล: ตัวจับเวลาที่ถูกทิ้ง listener ที่ซ้อนทับกัน การสมัครรับที่ไม่เคยถูกยกเลิก ทุกเอฟเฟกต์ที่ “เปิด” อะไรบางอย่างต้องปิดมันอีกครั้ง
useEffect(() => {
function onResize() {
setWidth(window.innerWidth);
}
window.addEventListener("resize", onResize);
return () => {
window.removeEventListener("resize", onResize);
};
}, []);useEffect(fn, []) ฟังก์ชัน fn จะถูกรันเมื่อใด?userId แต่อาร์เรย์ dependencies คือ [] ปัญหาคืออะไร?