ค้นหาเว็บไซต์

reactjs - React hooks ถูกเรียกใช้งานนอกลำดับ


ด้วยเหตุผลบางประการ ดูเหมือนว่า hook useMemo จะทำงานก่อน hook useEffect ซึ่งอยู่ตรงเหนือมัน ฉันเชื่อว่านี่เป็นเพราะฉันได้รับข้อผิดพลาด:

TypeError: ไม่สามารถอ่านคุณสมบัติ 'timestamp' ของ undefined ได้

ข้อผิดพลาดนี้ชี้ไปที่ datum.timestamp ในอาร์เรย์ของการพึ่งพาสำหรับ useEffect hook ตัวล่าสุด และเกิดขึ้นทุกครั้งที่ is_paused เปลี่ยนจาก false => true

ปัญหาตามที่ผมเห็นคือ hook useMemo กำลังพยายามดึงรายการจากอาร์เรย์ว่าง ซึ่งเป็นอาร์เรย์ที่ควรถูกตั้งค่าโดย useEffect ก่อนหน้านั้น

ฉันทำการบันทึกบางอย่าง และแน่นอนว่าฉันเห็นบันทึกใน useMemo แต่ไม่ใช่ใน useEffect

const [position, setPosition] = useState(MAX_HISTORY - 1);
const [data, setData] = useState<ExData[]>(new Array(MAX_HISTORY).fill({ content: {} }));
const paused_data_ref = useRef<ExData[]>([]);

useEffect(() => {
  const listener = (d: ExData) => {
    const new_data = data.slice(1);
    new_data.push(d);
    setData(new_data);
  };
  addListener(props.event_key, listener);
  return () => {
    removeListener(props.event_key);
  };
});

useEffect(() => {
  paused_data_ref.current = is_paused ? [...data] : [];
  if (is_paused) {
    console.log('copy data array');
  }
}, [is_paused, data]);

const datum = useMemo(() => {
  if (is_paused)
    console.log({
      position,
      data: paused_data_ref.current[position],
      arr: paused_data_ref.current
    });
  return is_paused ? paused_data_ref.current[position] : data[MAX_HISTORY - 1];
}, [is_paused, position, data]);

useEffect(() => {...}, [datum.timestamp])

คำตอบ #1

คุณถูกต้อง ฟังก์ชันที่ส่งไปยัง useEffect จะถูกเรียกหลังจากฟังก์ชันที่ส่งไปยัง useMemo

ตามเอกสารของ React:

ฟังก์ชันที่ส่งไปยัง useEffect จะทำงานหลังจากที่การแสดงผลถูกยืนยันบนหน้าจอแล้ว

นี่หมายความว่าการเรียก useEffect ทั้งหมดจะเกิดขึ้นหลังจากฟังก์ชันอื่น ๆ ในคอมโพเนนต์ของคุณ (รวมถึงฟังก์ชันที่ส่งต่อไปยัง useMemo) แม้ว่าจะวาง useEffect ไว้ก่อนในคอมโพเนนต์

https://reactjs.org/docs/hooks-reference.html