【原创】react-源码解析 - Component&Ref(3)

一、Component&PureComponent

 看到这个api想必大家再熟悉不过了,平常我们在react开发过程中写的组件都是继承自这个Component组件,比如我们在声明ClassComponent的时候extends的就是React.Component,在看源码只是我个人觉得写个class应该实现了很多复杂的功能比如说setState和render方法等,但是看了源码之后颠覆了我之前的认知:Component

Component(props, context, updater)

在源码中Component方法只是简单的对props和context进行了赋值操作,这两个传入的参数我们都很熟悉,最后这个updater参数我们我们接触到。通过源码我们看到在Component的原型上声明了setState方法:

// 原型上声明setState方法==接受两个参数partialState待更新的state,callback回调函数Component.prototype.setState = function(partialState, callback) {  

    invariant(// 判断传入参数是否合法--包括state和callBack

         typeof partialState ==='object'||typeof partialState ==='function'||partialState == null,

        'setState(...): takes an object of state variables to update or a'+'function which returns an         object of state variables.', );

        // setStated的时候在component  

        // 里面没有任何操作只是调用了初始化传入的this.updater里面的enqueueSetState方法 

        // 将this,state,callBack,和一个字符串‘setState’传入==>个人认为这个setState为一个type

         // enqueueSetState todo?此方法在react-dom中实现=后续

         this.updater.enqueueSetState(this, partialState, callback,'setState');

};

该函数内部只是判断了传入参数的合法性最后调用了Component中updater方法上的enqueueSetState。然后方法结束,这里去查了一下资料,这个方法具体的实现是在react-dom中完成的。为什么要这样做呢,因为在react中只是简单的提供了这个方法的入口,具体的调用需要看你在哪个平台下使用,比如在react-dom中和在react-native中的调用肯定是不同的。在原型上也声明了:

// forceUpdate-强制更新组件State方法

Component.prototype.forceUpdate = function(callback) { this.updater.enqueueForceUpdate(this, callback,'forceUpdate');};

看到这里我们发现只是调用了updater 的enqueueForceUpdate方法,个人认为跟字面意思一样,对state的进行了强制更新操作。PureComponent的用法我们不必再去赘述,该方法实际就是对Component方法进行了继承,但是多加了一个属性:

// 在原型上添加一个额外的isPureReactComponent属性/,标识是一个pureComponent

Object.assign(pureComponentPrototype, Component.prototype);pureComponentPrototype.isPureReactComponent =true;

isPureReactComponent用来说明是一个PureComponent。最后将这两个方法导出,到这里我们有关Componet的源码已经完结了,我们看到在react中其实没有太多复杂的操作,只是对传入参数的赋值,已经留下了一些函数入口。像更新渲染等操作实际都放在了react-dom中去完成。

二、createRef&ref

        在开发中我们通常会有这样的需求,有时候我们需要获取某个Dom节点或者拿到classComponent类型的子组件的实例,进而操作这个子组件。比如说我们需要通过在父级组件中调用到子组件中的方法,从而更新子组件,这里的更新就不仅仅局限于更新props,通常我们跟新props也不需要获得子组件的实例。 这里通过ref这个属性会让我们很容易操作子组件。

一般在现有版本中有三种使用ref的方法:

(1)string 类型ref ref="string" == {不推荐,下个大版本会废弃}

(2)function类型 ref = {ele => (this.childRef = ele )}

(3)React.createRef()

大致用法类似于这个样子,需要注意的是我们在使用ref时候,如果目标组件是一个function类型的Component一般来说这个时候拿到的ref肯定是undefined,因为functionComponent是没有实例的,后面我们会介绍一个叫做forward-ref的属性,这个属性可以让我们取到函数类型组件上去使用ref。接下来我们去看看createRef方法的源码:createRef

        这里的源码很简单只是创建了一个refObject在上面声明了一个为null的currenrt属性。然后将这个对象返回。其实这个源码看到这里也看不出ref到底是怎么挂载在组件的this上面的。这里应该是在react更新的过程中实现的,react中只有更新到结束一个完整的流程,至于到底是怎么挂载的ref我们接着往下读。

了解更多:react-source-code

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 40、React 什么是React?React 是一个用于构建用户界面的框架(采用的是MVC模式):集中处理VIE...
    萌妹撒阅读 1,075评论 0 1
  • 个人笔记, 转载请注明转载自 szhshp的第三边境研究所 Refs and the DOM In the t...
    szhielelp阅读 1,513评论 0 1
  • 写业务代码的时候 需要经常用到setState, 前几天review代码的时候, 又想了一下这个API, 发现对它...
    world_7735阅读 1,664评论 0 3
  • 3. JSX JSX是对JavaScript语言的一个扩展语法, 用于生产React“元素”,建议在描述UI的时候...
    pixels阅读 2,919评论 0 24
  • 说在前面 关于 react 的总结过去半年就一直碎碎念着要搞起来,各(wo)种(tai)原(lan)因(le)。心...
    陈嘻嘻啊阅读 6,941评论 7 41