Clashing useEffects?
ฉันรู้สึกว่าฉันเจอปัญหานี้บ่อยๆ
เมื่อใช้ chaining useEffects ที่จะทริกเกอร์หลังจากการเปลี่ยนแปลงสถานะฉันพบว่า useEffects บางอย่างใน chain มีการอ้างอิงที่ทับซ้อนกันซึ่งทำให้ทั้งคู่ถูกทริกเกอร์แทนที่จะเป็นตามลำดับหลังจากหนึ่งชุดเป็นสถานะ
ตัวอย่าง: ฉันกำลังเรียกใช้ chain of useEffects เมื่อทำการchapterIndexอัพเดต
let [ chapterIndex, setChapterIndex ] = useState<number | null>(0);
let [textTransitioning, setTextTransitioning] = useState<'out' | 'in' | null>(null);
useEffect(() => {
setTextTransitioning('out')
}, [chapterIndex])
useEffect(() => {
if (chapterIndex !== null) {
const {
current: chapter = null
} = chapterRefs.current[chapterIndex];
if (textTransitioning === 'in') {
chapter?.classList.add('in');
}
}
}, [textTransitioning, chapterIndex])
ฉันจะป้องกันไม่ให้ทั้งสองทำงานเมื่อมีchapterIndexการเปลี่ยนแปลงได้อย่างไร ฉันต้องการให้ useEffect ที่สองทำงานหลังจาก useEffect ครั้งแรกตั้งค่าเป็น textTransitioning เมื่อลบออกchapterIndexจากอาร์เรย์การอ้างอิงฉันได้รับข้อผิดพลาด: 'React Hook useEffect มีการอ้างอิงที่ขาดหายไป:' chapterIndex ' รวมไว้หรือลบอาร์เรย์อ้างอิง '
คำตอบ
useEffectรับ 2 อาร์กิวเมนต์ อันดับแรกคือฟังก์ชันที่จะเรียกใช้และตัวที่สองคืออาร์เรย์ของตัวแปรที่เรียกว่าอาร์เรย์การอ้างอิง อาร์กิวเมนต์ที่สองที่ใช้สำหรับเรียกใช้เอฟเฟกต์การใช้งานในขณะที่ตัวแปรตัวใดตัวหนึ่งในอาร์เรย์กำลังเปลี่ยนแปลง ดังนั้นหากคุณไม่ต้องการuseEffectถูกเรียกเมื่อมีการเปลี่ยนแปลงตัวแปรเฉพาะอย่าส่งผ่านไปในอาร์เรย์การอ้างอิง รหัสของคุณควรเป็นเช่นนั้น:
let [ chapterIndex, setChapterIndex ] = useState<number | null>(0);
let [textTransitioning, setTextTransitioning] = useState<'out' | 'in' | null>(null);
useEffect(() => {
setTextTransitioning('out')
}, [chapterIndex])
useEffect(() => {
if (chapterIndex !== null) {
const {
current: chapter = null
} = chapterRefs.current[chapterIndex];
if (textTransitioning === 'in') {
chapter?.classList.add('in');
}
}
}, [textTransitioning]
ฉันคิดว่ามันไม่ค่อยมีประสิทธิภาพที่จะทำให้อีกตัวuseEffectกระตุ้นหนึ่งแต่บางทีฉันอาจจะไม่เห็นภาพรวม
คุณต้องลบ "chapterIndex" ออกจากอาร์เรย์ใน useEffect ที่สอง ดังนั้นเมื่อใช้ useEffect ครั้งแรกมันจะอัปเดต "textTransitioning" ที่จะทำให้เกิดทริกเกอร์ useEffect ครั้งที่สอง
สำหรับการดำเนินการ useEffect แบบมีเงื่อนไขเพิ่มเติมคุณสามารถอ้างถึง https://reactjs.org/docs/hooks-effect.html