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