useEffect
ตะขอตอบสนอง
useEffect
Hook ช่วยให้คุณแสดงผลข้างเคียงในส่วนประกอบของคุณได้
ตัวอย่างของผลข้างเคียง ได้แก่ การดึงข้อมูล การอัปเดต DOM และตัวจับเวลาโดยตรง
useEffect
ยอมรับสองอาร์กิวเมนต์ อาร์กิวเมนต์ที่สองเป็นทางเลือก
useEffect(<function>, <dependency>)
ลองใช้ตัวจับเวลาเป็นตัวอย่าง
ตัวอย่าง:
ใช้setTimeout()
เพื่อนับ 1 วินาทีหลังจากการเรนเดอร์เริ่มต้น:
import { useState, useEffect } from "react";
import ReactDOM from "react-dom";
function Timer() {
const [count, setCount] = useState(0);
useEffect(() => {
setTimeout(() => {
setCount((count) => count + 1);
}, 1000);
});
return <h1>I've rendered {count} times!</h1>;
}
ReactDOM.render(<Timer />, document.getElementById('root'));
แต่เดี๋ยวก่อน!! ฉันนับต่อไปแม้จะนับเพียงครั้งเดียว!
useEffect
ทำงานบนทุกการเรนเดอร์ นั่นหมายความว่าเมื่อการนับเปลี่ยนไป การแสดงผลจะเกิดขึ้น ซึ่งจะทริกเกอร์เอฟเฟกต์อื่น
นี่ไม่ใช่สิ่งที่เราต้องการ มีหลายวิธีในการควบคุมเมื่อเกิดผลข้างเคียง
เราควรรวมพารามิเตอร์ที่สองซึ่งยอมรับอาร์เรย์เสมอ เราสามารถเลือกส่งการพึ่งพาuseEffect
ในอาร์เรย์นี้ได้
1. ไม่มีการพึ่งพาผ่าน:
useEffect(() => {
//Runs on every render
});
2. อาร์เรย์ว่าง:
useEffect(() => {
//Runs only on the first render
}, []);
3. อุปกรณ์ประกอบฉากหรือค่าสถานะ:
useEffect(() => {
//Runs on the first render
//And any time any dependency value changes
}, [prop, state]);
ดังนั้น เพื่อแก้ไขปัญหานี้ ให้เรียกใช้เอฟเฟกต์นี้กับการเรนเดอร์เริ่มต้นเท่านั้น
ตัวอย่าง:
เรียกใช้เอฟเฟกต์ในการเรนเดอร์เริ่มต้นเท่านั้น:
import { useState, useEffect } from "react";
import ReactDOM from "react-dom";
function Timer() {
const [count, setCount] = useState(0);
useEffect(() => {
setTimeout(() => {
setCount((count) => count + 1);
}, 1000);
}, []); // <- add empty brackets here
return <h1>I've rendered {count} times!</h1>;
}
ReactDOM.render(<Timer />, document.getElementById('root'));
ตัวอย่าง:
นี่คือตัวอย่างของuseEffect
Hook ที่ขึ้นอยู่กับตัวแปร หากcount
ตัวแปรอัปเดต เอฟเฟกต์จะทำงานอีกครั้ง:
import { useState, useEffect } from "react";
import ReactDOM from "react-dom";
function Counter() {
const [count, setCount] = useState(0);
const [calculation, setCalculation] = useState(0);
useEffect(() => {
setCalculation(() => count * 2);
}, [count]); // <- add the count variable here
return (
<>
<p>Count: {count}</p>
<button onClick={() => setCount((c) => c + 1)}>+</button>
<p>Calculation: {calculation}</p>
</>
);
}
ReactDOM.render(<Counter />, document.getElementById('root'));
หากมีการพึ่งพาหลายรายการ ก็ควรรวมไว้ในuseEffect
อาร์เรย์การพึ่งพา
การล้างเอฟเฟกต์
เอฟเฟกต์บางอย่างต้องการการล้างข้อมูลเพื่อลดการรั่วไหลของหน่วยความจำ
ระยะหมดเวลา การสมัครรับข้อมูล ผู้ฟังเหตุการณ์ และเอฟเฟกต์อื่นๆ ที่ไม่ต้องการอีกต่อไปควรถูกกำจัด
เราทำสิ่งนี้โดยใส่ฟังก์ชัน return ที่ส่วนท้ายของuseEffect
Hook
ตัวอย่าง:
ทำความสะอาดตัวจับเวลาที่ส่วนท้ายของuseEffect
ตะขอ:
import { useState, useEffect } from "react";
import ReactDOM from "react-dom";
function Timer() {
const [count, setCount] = useState(0);
useEffect(() => {
let timer = setTimeout(() => {
setCount((count) => count + 1);
}, 1000);
return () => clearTimeout(timer)
}, []);
return <h1>I've rendered {count} times!</h1>;
}
ReactDOM.render(<Timer />, document.getElementById("root"));
หมายเหตุ:เพื่อล้างตัวจับเวลา เราต้องตั้งชื่อมัน