การอ้างอิงว่างเปล่ากับ useMemo หรือ useCallback VS useRef


9

ในปัญหา GitHub นี้ฉันเสนอการเปลี่ยนแปลงเป็นหลัก:

x = useCallback( ... , []);

ถึง:

x = useRef( ... ).current;

ทั้งสองเหมือนกัน แต่ด้วยuseRefReact ไม่ได้เปรียบเทียบการพึ่งพา

ซึ่งการตอบกลับมาพร้อมกับคำถาม:

เคยมีสถานการณ์ที่การใช้งานน้อยกว่าการพึ่งพา Memo หรือ useCallback จะเป็นตัวเลือกที่ดีกว่า useRef หรือไม่?

ฉันไม่สามารถคิดได้ แต่ฉันอาจมองข้ามกรณีการใช้งานบางอย่าง

ทุกคนสามารถคิดสถานการณ์เช่นนี้ได้ไหม

คำตอบ:


5

เอกสารเกี่ยวกับ React Hooks API:

โปรดทราบว่า useRef จะไม่แจ้งเตือนคุณเมื่อมีการเปลี่ยนแปลงเนื้อหา การกลายเป็นคุณสมบัติ. ปัจจุบันไม่ทำให้เกิดการแสดงผลซ้ำ ... การใช้การอ้างอิงกลับช่วยให้มั่นใจได้ว่าแม้ว่าองค์ประกอบลูกจะแสดงโหนดที่วัดได้ในภายหลัง (เช่นตอบสนองต่อการคลิก) เรายังคงได้รับการแจ้งเตือนใน parent ส่วนประกอบและสามารถปรับปรุงการวัด

คุณสามารถอ่านเพิ่มเติมได้ที่นี่และที่นี่


ฉันเดาว่านี่จะตอบคำถามได้ แต่ฉันคิดว่ามันไม่ถูกต้อง ในตัวอย่าง Sandbox React การเปลี่ยนuseCallback(x,[])เป็นการuseRef(x)ทำงานแบบเดียวกัน
Izhaki

useRef(x).currentนั่นคือ.
Izhaki

ฉันหวังว่าฉันผิด แต่ฉันได้ทำกรณีสำหรับสาเหตุที่เอกสารไม่ถูกต้อง: github.com/reactjs/reactjs.org/issues/2570
Izhaki

ฉันไม่แน่ใจทั้งหมดเกี่ยวuseCallback(cb, [])กับuseRef(cb).currentตัวฉันเอง แม้ว่าuseMemo(cb, [])จะแตกต่างจากuseRef(cb).currentในแง่ที่ว่าuseMemo"จะคำนวณค่าที่บันทึกความจำใหม่เมื่อการอ้างอิงหนึ่งมีการเปลี่ยนแปลง" เมื่อเทียบกับuseRefซึ่งมักจะคำนวณค่าใหม่ไม่ว่าจะเกิดอะไรขึ้น
irasuna

useRefไม่ต้องคำนวณซ้ำ - มันจะคืนค่าเริ่มต้นเสมอ
Izhaki

1

ในขณะที่คุณสามารถใช้ useRef เพื่อเลียนแบบ useCallback หรือด้วยการพึ่งพาที่ว่างเปล่าคุณไม่สามารถใช้มันสำหรับสถานการณ์ที่เป็นไปได้ทั้งหมดของ useCallback ซึ่งจะทำการจำลองเมื่อการพึ่งพาใด ๆ เปลี่ยนแปลง

นอกจากนี้มันจะไม่สร้างความแตกต่างด้านประสิทธิภาพมากนักหากคุณใช้useCallback with empty dependencyหรือ useRef เนื่องจากไม่จำเป็นต้องทำการเปรียบเทียบหนัก ๆ

นอกจากนี้หากคุณเปลี่ยนฟังก์ชั่นการใช้งานเล็กน้อยเพื่อให้คุณต้องสร้างมันขึ้นมาใหม่เมื่อมีการเปลี่ยนแปลงพารามิเตอร์โดยเฉพาะคุณสามารถอัปเดตการใช้งานด้วยuseCallbackและเพิ่มในพารามิเตอร์พิเศษเป็นการพึ่งพา อย่างไรก็ตามถ้าคุณใช้กับ useRef คุณต้องย้อนกลับuseCallback


1
ขอบคุณ ตามชื่อเรื่องแสดงว่านี่เป็นกรณีการอ้างอิงที่ว่างเปล่าอย่างเคร่งครัด
Izhaki

1
@Izhaki ฉันเข้าใจว่าคำถามของคุณคือการพึ่งพาที่ว่างเปล่าอย่างเคร่งครัดและนั่นคือเหตุผลที่ฉันพูดถึงว่าไม่มีความแตกต่างในกรณีของการพึ่งพาที่ว่างเปล่า แต่เมื่อคุณพยายามที่จะเพิ่มการเปลี่ยนแปลงมากขึ้นคุณอาจต้องปรับเปลี่ยนเล็กน้อย
Shubham Khatri

0

เนื่องจากเอาต์พุตของ useRef (() => {... }) ปัจจุบันไม่แน่นอน

ซึ่งอาจทำให้เกิดผลข้างเคียงที่แปลกในรหัสของคุณ ฉันสามารถเปลี่ยนมูลค่าของกระแสได้ตลอดเวลา https://codesandbox.io/s/confident-monad-vjeuw

นั่นจะเป็นกรณีที่ไม่ต้องการใช้ useRef


1
แต่x = useRef(value).currentจะไม่ส่งคืนอินสแตนซ์ที่ไม่แน่นอน - refจะไม่ถูกส่งคืน currentคือ. นั่นเป็นเช่นเดียวกับuseCallbackรุ่น
Izhaki
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.