ReactRef模块提供方法用于向顶层用户自定义组件实例添加或移除refs、或比较refs是否需要更新。通过ReactRonconcile模块间接被ReactCompositeComponent模块调用。
'use strict'; // 调用顶层用户自定义组件的attachRef、detachRef方法,用于添加refs属性 var ReactOwner = require('./ReactOwner'); var ReactRef = {}; // 向用户自定义组件实例添加ref,值为子组件实例component.getPublicInstance() // 参数ref为定义在顶层用户自定义组件下的ref属性配置 // 函数(component)=>{this.C=component},或string形式,将向顶层用户自定义组件添加this.refs[ref]属性 // 参数component为子组件的ReactCompositeComponent实例 // 调用getPublicInstance获取ReactComponent或ReactDomComponent实例 // 参数owner为顶层用户自定义组件的挂载类ReactCompositeComponent实例 function attachRef(ref, component, owner) { if (typeof ref === 'function') { // 函数由用户自定义组件owner调用ReactRenconciler中方法执行,this指向owner ref(component.getPublicInstance()); } else { // 间接通过用户自定义组件实例owner的attachRef方法,向该实例添加this.refs[ref]属性 ReactOwner.addComponentAsRefTo(component, ref, owner); } } // 移除用户自定义组件的ref function detachRef(ref, component, owner) { if (typeof ref === 'function') { ref(null); } else { ReactOwner.removeComponentAsRefFrom(component, ref, owner); } } // 调用attachRef函数,为顶层用户自定义组件实例element._owner添加ref,其值为子组件实例 // 参数instance为顶层用户自定义组件实例下挂载的子组件实例,ReactCompositeComponent实例 // 调用getPublicInstance获取ReactComponent或ReactDomComponent实例 // 参数element为ReactCompositeComponent实例中创建的racetNode,即以ReactComponent或ReactDomComponent为构造函数的元素 // 特别的,element._owner为顶层用户自定义组件的实例 ReactRef.attachRefs = function (instance, element) { if (element === null || typeof element !== 'object') { return; } var ref = element.ref;// 用户设置的元素的ref属性,函数或者字符串 if (ref != null) { // element._owner,当使用JSX方式书写reactNode时,其_owner属性指向用户自定义组件的挂载类ReactCompositeComponent实例 // 用户自定义组件即容器组件的render方法中调用React.createElement时将注入该容器组件的相关ReactCompositeComponent实例 attachRef(ref, instance, element._owner); } }; // 当元素的ref属性设置变更,或者顶层用户自定义组件变更且ref为字符串时,更新refs ReactRef.shouldUpdateRefs = function (prevElement, nextElement) { var prevRef = null; var prevOwner = null; if (prevElement !== null && typeof prevElement === 'object') { prevRef = prevElement.ref; prevOwner = prevElement._owner; } var nextRef = null; var nextOwner = null; if (nextElement !== null && typeof nextElement === 'object') { nextRef = nextElement.ref; nextOwner = nextElement._owner; } return prevRef !== nextRef || // 顶层用户自定义组件已变更,然而ref为函数形式,无需更新refs typeof nextRef === 'string' && nextOwner !== prevOwner; }; // 调用detachRef函数,移除顶层用户自定义组件实例element._owner的ref ReactRef.detachRefs = function (instance, element) { if (element === null || typeof element !== 'object') { return; } var ref = element.ref; if (ref != null) { detachRef(ref, instance, element._owner); } }; module.exports = ReactRef;