本文引伸与Dan Abramov的博文, How Are Function Components Different from Classes?, 感兴趣的同窗能够直接看原文。 本文在Dan的文章的基础,作了一些本身的思考。javascript
当点击button,延迟3s后,两个组件都会在控制台打印props.user属性。咋一看没啥区别,可是若是在延迟的3s的之间,咱们修改了props.user属性。class组件会打印最新的值,而function组件打印的仍是旧值。java
Dan给出了一个在线的Demoreact
这是由于,在React中props是不可变的。可是this不是,this是一直是可变。数组
咱们能够组件render时,利用javascript的闭包特性,捕获props。咱们知道,在javascript中函数执行完成后,函数内部建立的变量,会被javascript的垃圾回收机制所回收。闭包
可是若是在回调函数中,咱们依赖了这个变量,这个变量就不会被回收。咱们在render函数执行的时候,建立了props常量。并在定时器的callback中引用了它。它在定时器的callback执行完成前,会一直存在在内存中。因此咱们在执行callback时,打印的依然是旧的值。函数
限于本人能力有限,react的源码对于我来讲实在有些困难😂。咱们将从preact源码,一窥究竟。this
在preact中,会将组件实例的props属性做为参数,传入组件的render函数中。3d
当实例的props属性发生修改时,class组件直接使用this(组件的实例),因此能够直接获取组件最新的props。而在函数组件中,以前的props参数,已经由于javascript闭包的特性,保存在内存之中,没法从外部进行修改。因此在定时器执行callback时,打印的仍是旧值。code
若是你在理解上还有些困难,能够尝试理解,如下简化的代码。说明了,为何函数组件会打印旧值。component
咱们能够尝试利用useRef。固然这种使用useRef的方式,不是广泛的