评论

react源码解析--React组件

本篇文章主要介绍了Component和PureComponent的定义以及使用方式,最后也介绍了无状态功能性组件的定义方式。

说明:目前react发展到现在,其应用场景已经包含web页面、native页面、node服务端,它所对应的渲染方式也是各不相同的,所以React不能局限固定渲染UI的方式,那么在React的核心代码中,我们只会看到相关的组件定义,而并不涉及具体的组件渲染,组件的渲染会在之后的React-dom源码解析中说明。所以本篇文章以定义说明和使用为主。
本文接上篇文章:react源码解析–开篇

一、定义

1、首先是react引入ReactBaseClasses文件中定义了两个构造函数(或者类):Component,和PureComponent。

2、Component的定义如下


这里仅仅是组件的构造函数的定义,有三个参数,props、context、updater,props为传入组件的数据、context为上下文,updater为render(例如ReactDOM.render)注入,后续文章会讲,而它的默认值ReactNoopUpdateQueue只是一个对象,定义了enqueueForceUpdate(强制更新state,不会调用shouldComponentUpdate)、enqueueReplaceState(异步、替换state的数据)、enqueueSetState(即setState)方法。
Component的原型上挂了一些方法和属性,isReactComponent属性,setState方法,forceUpdate方法,主要还是调用构造函数中传入的updater的方法,代码如下:

3、PureComponent的定义如下


PureComponent继承自Component,这两个类基本相同,唯一的区别是PureComponent的原型上多了一个标识:isPureReactComponent。首先是创建了一个ComponentDummy构造函数,他的原型指到Component的原型;然后创建了一个PureComponent, 加上了和Component一样的属性。PureComponent的原型指向ComponentDummy的实例;修改PureComponent原型的constructor属性使其正确指向PureComponent的构造函数,并挂一个isPureReactComponent的属性。为了减少向上去查找原型链次数,用了一个assign直接将Component原型的东西拷贝到PureComponent的原型上。

二、Component使用


Hello 继承自 React.Component,在构造函数中,通过 super() 来调用父类的构造函数,state是在构造函数中通过 this.state 来进行赋值的,组件的props是在类Greeting上创建的。用这种方式创建组件的时候,React 并没有对内部函数进行 this 绑定,如果在回调函数中保持正确的 this ,需要手动对函数进行 this 绑定,如上面的 handleClick 函数,在构造函数中对 this 进行了绑定。
当组件的 props 或者 state 发生变化的时候,React会对组件当前的 Props 和 State 分别与nextProps 和 nextState 进行比较,当发现变化时,就会对当前组件以及子组件进行重新渲染,否则就不渲染。有时候为了避免组件进行不必要的重新渲染,我们可以通过定义 shouldComponentUpdate 来优化性能。

当然这里也只是对state和props的个别属性进行了浅比较,其实如果只是对state和props下的所有属性进行浅比较的话,可以直接使用PureComponent。

三、PureComponent的使用


大多数情况下, 我们使用 PureComponent 能够简化我们的代码,并且提高性能,但是 PureComponent 的自动为我们添加的shouldComponentUpate 函数,只是对 props 和 state 进行浅比较(shadow comparison),当 props 或者 state 本身是嵌套对象或数组等时,浅比较并不能得到预期的结果,这会导致实际的 props 和 state 发生了变化,但组件却没有更新的问题。

四、无状态功能性组件

上面创建组件的方式,都是用来创建包含状态和用户交互的复杂组件,当组件本身只是用来展示,所有数据都是通过 props 传入的时候,我们可以使用 Stateless Functional Component(无状态功能性组件) 来快速创建组件。

这种组件,没有自身的状态,相同的 props 输入,必然会获得完全相同的组件展示。因为不需要关心组件的一些生命周期函数和渲染的钩子,所以不用继承自 Component 显得更简洁。

五、小结

本篇文章主要介绍了Component和PureComponent的定义以及使用方式,最后也介绍了无状态功能性组件的定义方式,Component相对来说使用场景会相对复杂,自由度也更高、PureComponent则是对组件状态有变化时自动浅比较来决定是否要渲染更新、无状态功能性组件则是只对传入数据进行展示无内部状态。

ps:下一篇预告《react源码解析–ReactElement》

最后一次编辑于  2020-01-23  
点赞 10
收藏
评论
登录 后发表内容