Clashing useEffects?

Sep 22 2020

ฉันรู้สึกว่าฉันเจอปัญหานี้บ่อยๆ

เมื่อใช้ 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 ' รวมไว้หรือลบอาร์เรย์อ้างอิง '

คำตอบ

Itaywazana Sep 22 2020 at 09:54

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กระตุ้นหนึ่งแต่บางทีฉันอาจจะไม่เห็นภาพรวม

YogeshChaturvedi Sep 22 2020 at 09:58

คุณต้องลบ "chapterIndex" ออกจากอาร์เรย์ใน useEffect ที่สอง ดังนั้นเมื่อใช้ useEffect ครั้งแรกมันจะอัปเดต "textTransitioning" ที่จะทำให้เกิดทริกเกอร์ useEffect ครั้งที่สอง

สำหรับการดำเนินการ useEffect แบบมีเงื่อนไขเพิ่มเติมคุณสามารถอ้างถึง https://reactjs.org/docs/hooks-effect.html