「React」函數組件與Class組件有何本質不一樣?

image

📖前言

本文引伸與Dan Abramov的博文, How Are Function Components Different from Classes?, 感興趣的同窗能夠直接看原文。 本文在Dan的文章的基礎,作了一些本身的思考。javascript

image

🤔兩個組件有何不一樣

image

當點擊button,延遲3s後,兩個組件都會在控制檯打印props.user屬性。咋一看沒啥區別,可是若是在延遲的3s的之間,咱們修改了props.user屬性。class組件會打印最新的值,而function組件打印的仍是值。java

Dan給出了一個在線的Demoreact

這是由於,在React中props是不可變的。可是this不是,this是一直是可變。數組

💡如何在class組件中,打印出舊值?

咱們能夠組件render時,利用javascript的閉包特性,捕獲props。咱們知道,在javascript中函數執行完成後,函數內部建立的變量,會被javascript的垃圾回收機制所回收。閉包

可是若是在回調函數中,咱們依賴了這個變量,這個變量就不會被回收。咱們在render函數執行的時候,建立了props常量。並在定時器的callback中引用了它。它在定時器的callback執行完成前,會一直存在在內存中。因此咱們在執行callback時,打印的依然是的值。函數

image

⚛️從源碼的角度進行分析

限於本人能力有限,react的源碼對於我來講實在有些困難😂。咱們將從preact源碼,一窺究竟。this

image

在preact中,會將組件實例的props屬性做爲參數,傳入組件的render函數中。3d

當實例的props屬性發生修改時,class組件直接使用this(組件的實例),因此能夠直接獲取組件最新的props。而在函數組件中,以前的props參數,已經由於javascript閉包的特性,保存在內存之中,沒法從外部進行修改。因此在定時器執行callback時,打印的仍是舊值。code

若是你在理解上還有些困難,能夠嘗試理解,如下簡化的代碼。說明了,爲何函數組件會打印值。component

image

⚓️如何在funtion組件中,打印出新值?

咱們能夠嘗試利用useRef。固然這種使用useRef的方式,不是廣泛的

image

✍️參考

相關文章
相關標籤/搜索