React和DOM的那些事-节点更新

点击进入React源码调试仓库。

React的更新最终要落实到页面上,所以本文主要讲解DOM节点(HostComponent)和文本节点(HostText)的更新,对于前者来说更新是props的更新,对后者来说更新是文字内容的更新。

commitWork是节点更新的入口。

function commitMutationEffectsImpl(  fiber: Fiber,  root: FiberRoot,  renderPriorityLevel,) {  ...  switch (primaryEffectTag) {    ...    case Update: {      const current = fiber.alternate;      commitWork(current, fiber);      break;    }  }}

commitWork重点处理了HostComponent和HostText。

HostText的更新

更新HostText,实际上也就是更新文本内容,过程比较简单,最终调用commitTextUpdate来设置文本内容。

function commitWork(current: Fiber | null, finishedWork: Fiber): void {  ...  switch (finishedWork.tag) {    ...    case HostText: {      const textInstance: TextInstance = finishedWork.stateNode;      const newText: string = finishedWork.memoizedProps;      const oldText: string =        current !== null ? current.memoizedProps : newText;      commitTextUpdate(textInstance, oldText, newText);      return;    }  }  ...}

HostComponent的更新

更新HostComponent是更新fiber节点上的props,这需要使用到在render阶段的complete过程中节点props的diff结果:fiber.updateQueue。再来回顾壹下它的形式:数组,以2为单位,index为偶数的是key,为奇数的是value。

[ 'style', { color: 'blue' }, title, '测试标题' ]

整个更新过程就是遍历数组,最终调用updateDOMProperties将属性和值设置到DOM节点上。

function updateDOMProperties(  domElement: Element,  updatePayload: Array<any>,  wasCustomComponentTag: boolean,  isCustomComponentTag: boolean,): void {  // 遍历updateQueue数组,应用更新  for (let i = 0; i < updatePayload.length; i += 2) {    const propKey = updatePayload[i];    const propValue = updatePayload[i + 1];    if (propKey === STYLE) {      setValueForStyles(domElement, propValue);    } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {      setInnerHTML(domElement, propValue);    } else if (propKey === CHILDREN) {      setTextContent(domElement, propValue);    } else {      setValueForProperty(domElement, propKey, propValue, isCustomComponentTag);    }  }}

总结

整个节点的更新过程比较单纯,将新的属性值或者新的文本内容设置到节点上,并不涉及其他复杂的操作,比较好理解。


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章