函数组件与类组件有什么区别?如果你了解React Hooks(后文简称Hooks),在这里请抛开Hooks回答这个问题。
本节不讨论状态(state)和生命周期,先看一个函数调用的示例,代码如下。
getName是一个纯函数,不产生任何副作用,执行结束后,它的执行上下文和活动对象会被销毁,前后两次调用互不影响。对于不使用任何Hooks的函数组件而言,它也是纯函数,那么对于函数组件前后两次渲染,你能得出与调用getName函数类似的结论吗?
下面用类组件和函数组件实现相同的功能来对比二者的区别。在浏览器上显示一个按钮,单击按钮调用props中的方法来更新父组件的状态,隔1s之后打印this.props.count的值。类组件的代码如下。
函数组件的代码如下。
FuncCom和ClassCom组件的父级相同,代码如下。
观察上述代码可以发现,传递给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属性能让两个组件打印出相同的值。