![低代码平台开发实践:基于React](https://wfqqreader-1252317822.image.myqcloud.com/cover/617/50417617/b_50417617.jpg)
1.1 函数组件与类组件
函数组件与类组件有什么区别?如果你了解React Hooks(后文简称Hooks),在这里请抛开Hooks回答这个问题。
本节不讨论状态(state)和生命周期,先看一个函数调用的示例,代码如下。
![](https://epubservercos.yuewen.com/10262B/29686504404601406/epubprivate/OEBPS/Images/978-7-111-74689-8_11_01.jpg?sign=1738811628-cnTIEspB2e5orig1EWNQTswucQBTBmj7-0-d406d783695ba8255381a89d667c3be1)
getName是一个纯函数,不产生任何副作用,执行结束后,它的执行上下文和活动对象会被销毁,前后两次调用互不影响。对于不使用任何Hooks的函数组件而言,它也是纯函数,那么对于函数组件前后两次渲染,你能得出与调用getName函数类似的结论吗?
下面用类组件和函数组件实现相同的功能来对比二者的区别。在浏览器上显示一个按钮,单击按钮调用props中的方法来更新父组件的状态,隔1s之后打印this.props.count的值。类组件的代码如下。
![](https://epubservercos.yuewen.com/10262B/29686504404601406/epubprivate/OEBPS/Images/978-7-111-74689-8_12_01.jpg?sign=1738811628-Huz7IEV8Gnn9CGQtL81w5anB5pKnK26H-0-b675a05864c395fa210ad8c2f63a32b9)
函数组件的代码如下。
![](https://epubservercos.yuewen.com/10262B/29686504404601406/epubprivate/OEBPS/Images/978-7-111-74689-8_12_02.jpg?sign=1738811628-R8tHNvBebxhkaHNcShAGGVZ1u7zVMM3B-0-687376a217fc2d0beaa8858837338339)
FuncCom和ClassCom组件的父级相同,代码如下。
![](https://epubservercos.yuewen.com/10262B/29686504404601406/epubprivate/OEBPS/Images/978-7-111-74689-8_12_03.jpg?sign=1738811628-02RmayLRoaqNkWxmPYDQ8F5gWCgqJlAz-0-c544e77f4210b22fa964f65971c743c3)
![](https://epubservercos.yuewen.com/10262B/29686504404601406/epubprivate/OEBPS/Images/978-7-111-74689-8_13_01.jpg?sign=1738811628-opdvLgw4MgGkCVqRxugIbAUVd3FGTkpI-0-8919775c305d2ee3cbab613cc74b8657)
观察上述代码可以发现,传递给FuncCom和ClassCom组件的props是一样的,但在浏览器界面中单击组件的按钮,开发者工具打印的结果不一样,FuncCom组件打印的值为0,ClassCom组件打印的值为1。
现在揭晓答案,单击FuncCom和ClassCom组件中的按钮都会使父级重新渲染,从而导致FuncCom和ClassCom重新渲染。ClassCom是类组件,重新渲染不会创建新的组件实例,在setTimeout的回调函数中this.props拿到了最新的值。FuncCom是函数组件,重新渲染会创建新的执行环境和活动变量,所以访问props,无论何时拿到的都是调用FuncCom时传递给它的参数,该参数不可变。
FuncCom和ClassCom组件打印出不同的值,原因在于props不可变但类组件实例是可变的,访问this.props将始终得到类组件最新的props。将ClassCom的this.props赋值给一个变量,在setTimeout的回调函数中用该变量访问count属性能让两个组件打印出相同的值。