当前位置: 首页 > news >正文

枣庄网站开发公司珠江夜游微信公众号

枣庄网站开发公司,珠江夜游微信公众号,域名一定要备案吗,photoshop网课培训ref的实现过程 1 #xff09;概述 在更新流程当中如何去设置ref上面的对象的过程在我们创建fiber的时候去处理ref这个属性那我们什么时候创建fiber对象? 就是我们去更新某一个节点#xff0c;然后要去调和它的子节点的时候这个时候我们会对每一个子节点去创建这个fiber对象…ref的实现过程 1 概述 在更新流程当中如何去设置ref上面的对象的过程在我们创建fiber的时候去处理ref这个属性那我们什么时候创建fiber对象? 就是我们去更新某一个节点然后要去调和它的子节点的时候这个时候我们会对每一个子节点去创建这个fiber对象 创建这个fiber对象的过程我们就会去处理这个refcommit开始之前先detach 2 源码 定位到 packages/react-reconciler/src/ReactChildFiber.js#L1108 function reconcileSingleElement(returnFiber: Fiber,currentFirstChild: Fiber | null,element: ReactElement,expirationTime: ExpirationTime, ): Fiber {// ... 跳过很多代码while (child ! null) {// TODO: If key null and child.key null, then this only applies to// the first item in the list.if (child.key key) {if (child.tag Fragment? element.type REACT_FRAGMENT_TYPE: child.elementType element.type) {// ... 跳过很多代码// 注意这里existing.ref coerceRef(returnFiber, child, element);// ... 跳过很多代码} else {deleteRemainingChildren(returnFiber, child);break;}} else {deleteChild(returnFiber, child);}child child.sibling;}if (element.type REACT_FRAGMENT_TYPE) {// ... 跳过很多代码return created;} else {// ... 跳过很多代码// 注意这里created.ref coerceRef(returnFiber, currentFirstChild, element);created.return returnFiber;return created;} }进入 coerceReffunction coerceRef(returnFiber: Fiber,current: Fiber | null,element: ReactElement, ) {let mixedRef element.ref; // 拿到 ref// function ref 和 object ref 是不需要经过特殊处理的// 自己处理节点对象挂载到 class component 的 this 上面这一个过程// 对于 string ref它只是一个string它没有任何功能它的挂载是要react这边来帮着去做的// 所以这边主要去 去处理一下 string ref 的一个实现过程if (mixedRef ! null typeof mixedRef ! function typeof mixedRef ! object) {if (__DEV__) {// 跳过}// 在 ReactElement.js 中可看到 _owner 是 ReactCurrentOwner.current// 在更新 class component 的时候调用 finishClassComponent 就会设置// ReactCurrentOwner.current workInProgress// 在后面调用 instance.render() 去重新渲染子节点的过程中// 就会调用 React.createElement, 因为 ref 只有// 因为ref它肯定是在 class component它这个过程当中才会被创建的// 因为只有 class component 有 this 去挂载 ref 的那个对象// 所以我们在调用 instance.render() 的时候那么在 react element 里面拿到的这个 ReactCurrentOwner.current// 就是我们那个 class component它对应的fiber对象if (element._owner) {const owner: ?Fiber (element._owner: any);let inst;// 有了这个 fiber 对象之后那么我们可以拿到它的 _owner拿到它的 _owner 之后// 如果 owner 的存在ownerFiber 就等于 ownerif (owner) {const ownerFiber ((owner: any): Fiber);invariant(ownerFiber.tag ClassComponent,Function components cannot have refs.,);// 然后它的 inst 就是 ownerFiber.stateNode// 也就是我们 class component那个 instance 也就是 thisinst ownerFiber.stateNode;}invariant(inst,Missing owner for string ref %s. This error is likely caused by a bug in React. Please file an issue.,mixedRef,);const stringRef mixedRef;// Check if previous string ref matches new string ref// 有了 inst 之后可以为它去构建一个方法// 这边是一个对比就是说我们每次设置完这个 ref 之后都会给它设置一个属性 _stringRef// 用来在我们更新这个组件的过程当中去判断一下它这个 _stringRef 对应的那个值是否有变化if (current ! null current.ref ! null typeof current.ref function current.ref._stringRef stringRef) {// 如果没有变化我们不需要去为它重新生成一个方法了我们只需要 return 就可以了return current.ref;}// 对于新的情况我们就需要去生成一个方法// 这个 value 就是后期dom节点或者是class instance它被挂载的时候// 它会调用这个 ref 这个方法然后传入它自己的那个实例// 也就是给一个 dom 节点设置了 ref 之后在后期就是 commitRoot 的过程当中这个节点最终被挂载到 dom 上面了// 这个时候会把这个 dom 节点去调用 ref 这个方法然后作为参数传入进来// 这个时候去设置到就是当前去创建这个 ref 的时候这个 class component的对象上面的 ref 这个属性上面// 也就达到了 ref 可以设置在 this.refs 上面这个功能const ref function(value) {let refs inst.refs;if (refs emptyRefsObject) {// This is a lazy pooled frozen object, so we need to initialize.refs inst.refs {};}if (value null) {delete refs[stringRef];} else {refs[stringRef] value;}};ref._stringRef stringRef;return ref;} else {invariant(typeof mixedRef string,Expected ref to be a function, a string, an object returned by React.createRef(), or null.,);invariant(element._owner,Element ref was specified as a string (%s) but no owner was set. This could happen for one of the following reasons:\n 1. You may be adding a ref to a function component\n 2. You may be adding a ref to a component that was not created inside a components render method\n 3. You have multiple copies of React loaded\n See https://fb.me/react-refs-must-have-owner for more information.,mixedRef,);}}return mixedRef; }这就是在调和子节点的过程当中要处理 ref 的一个内容因为 stringRef 它是一个特殊的存在它没有什么功能性而对于 function ref 传进来的就是一个方法可以直接调用它而对于 object ref只需要设置它的 .current 就可以了这也是为什么以后 string ref 要被移除的一个原因因为它比较麻烦需要我们自己去处理这是我们去处理 ref 这个属性的过程 关于 commit开始之前先detach 定位到 packages/react-reconciler/src/ReactFiberScheduler.js#L392 查看 commitAllHostEffects function commitAllHostEffects() {while (nextEffect ! null) {if (__DEV__) {ReactCurrentFiber.setCurrentFiber(nextEffect);}recordEffect();const effectTag nextEffect.effectTag;if (effectTag ContentReset) {commitResetTextContent(nextEffect);}// 对于有 ref 这个 SideEffect 的节点// 如果current不等于null要先调用 commitDetachRef// 先把这个 ref 从之前挂载的地方去给它卸载下来看下这个 commitDetachRefif (effectTag Ref) {const current nextEffect.alternate;if (current ! null) {commitDetachRef(current);}}// The following switch statement is only concerned about placement,// updates, and deletions. To avoid needing to add a case for every// possible bitmap value, we remove the secondary effects from the// effect tag and switch on that value.let primaryEffectTag effectTag (Placement | Update | Deletion);switch (primaryEffectTag) {case Placement: {commitPlacement(nextEffect);// Clear the placement from effect tag so that we know that this is inserted, before// any life-cycles like componentDidMount gets called.// TODO: findDOMNode doesnt rely on this any more but isMounted// does and isMounted is deprecated anyway so we should be able// to kill this.nextEffect.effectTag ~Placement;break;}case PlacementAndUpdate: {// PlacementcommitPlacement(nextEffect);// Clear the placement from effect tag so that we know that this is inserted, before// any life-cycles like componentDidMount gets called.nextEffect.effectTag ~Placement;// Updateconst current nextEffect.alternate;commitWork(current, nextEffect);break;}case Update: {const current nextEffect.alternate;commitWork(current, nextEffect);break;}case Deletion: {commitDeletion(nextEffect);break;}}nextEffect nextEffect.nextEffect;}if (__DEV__) {ReactCurrentFiber.resetCurrentFiber();} }定位到 packages/react-reconciler/src/ReactFiberCommitWork.js#L623 查看 commitDetachRef function commitDetachRef(current: Fiber) {const currentRef current.ref;if (currentRef ! null) {if (typeof currentRef function) {currentRef(null);} else {currentRef.current null;}} }到 commitAllLifeCycles 时 function commitAllLifeCycles(finishedRoot: FiberRoot,committedExpirationTime: ExpirationTime, ) {// ... 跳过很多代码while (nextEffect ! null) {// ... 跳过很多代码// 注意这里if (effectTag Ref) {recordEffect();commitAttachRef(nextEffect);}// ... 跳过很多代码} }再次调用 commitAttachRef 把真正的更新过后的节点给它挂载上去function commitAttachRef(finishedWork: Fiber) {const ref finishedWork.ref;if (ref ! null) {const instance finishedWork.stateNode;let instanceToUse;switch (finishedWork.tag) {case HostComponent:instanceToUse getPublicInstance(instance); // 获取到了 dom节点对应到的实例break;default:instanceToUse instance;}// function 的处理if (typeof ref function) {ref(instanceToUse);} else {// 跳过if (__DEV__) {if (!ref.hasOwnProperty(current)) {warningWithoutStack(false,Unexpected ref object provided for %s. Use either a ref-setter function or React.createRef().%s,getComponentName(finishedWork.type),getStackByFiberInDevAndProd(finishedWork),);}}// 其他情况直接设置ref.current instanceToUse;}} }如果是 HostComponent 执行 getPublicInstanceexport function getPublicInstance(instance: Instance): * {return instance; }这个时候就完成了对于我们的 class component 上面的this去挂载ref它的一个过程这边最主要的是去注意对于 stringRef 在调和子节点的过程当中会对它进行一个预先的处理把它转化成一个方法以上就是ref在整个react应用更新的过程当中如何被实现的原理
http://www.hkea.cn/news/14428435/

相关文章:

  • 营销型网站建站建设银行广州招聘网站
  • 网站建设收费标准新闻wordpress本地搭建网站
  • asp.net做的网站文字控件随窗口大小不变化苏州做网站公司哪家比较好
  • 官方网站建设最重要的是什么解封后中国死了多少人
  • 搜狗网站seo什么网站可以在线做考教师岗位的题
  • 贵阳网站开发制作公司房地产网站互动设计公司
  • 网站源码下载后怎么布置网站打开速度多少时间
  • 网站是用什么软件做的吗站内免费推广有哪些
  • mt4网站建设网站打开空白页面
  • 上海物流公司网站建设青岛网站建设套餐报价
  • 建站平台选择建议网站ui界面设计模板
  • 动漫制作技术专业常识优化设计六年级上册数学答案
  • 三门峡网站设计帝国建站系统
  • 五金喷漆东莞网站建设购买域名和网站
  • 黄金网站软件免费wordpress百度云下载
  • 美橙建站怎么样河北seo技术
  • 个人主页静态网站梅河口网站建设
  • 深圳建设局网站网站项目
  • php 网站 教程邳州徐州网站开发
  • win2008网站404如何在网站做电子报
  • 注册的空间网站吗优狐网站建设
  • 怎么在网站做浮动图标龙岩建设局网站
  • 政务网站的建设时期的概述外贸网站怎么建设
  • 网站后台打打开空白男的如何自己解决生理问题
  • 国家城乡建设网站网站建设助您购选
  • 长春高端网站建设蓝色的网站登录页面模版
  • 免费的网站开发平台网站开发的目的实习报告
  • 微芒科技网站建设top陕西 网站建设首选公司
  • 做网站怎么做鼠标跟随怎样才能有自己的网站
  • 网站建设要考建设网站需要的硬件设备