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

网站建设要咨询哪些内容温州免费个人网站制作公司

网站建设要咨询哪些内容,温州免费个人网站制作公司,wordpress如何制作二维码,自己在线制作logo这一章节就来讲讲ReactDOM.render()方法的内部实现与流程吧。 因为初始化的源码文件部分所涵盖的内容很多#xff0c;包括创建渲染、更新渲染、Fiber树的创建与diff#xff0c;element的创建与插入#xff0c;还包括一些优化算法#xff0c;所以我就整个的React执行流程画了…这一章节就来讲讲ReactDOM.render()方法的内部实现与流程吧。 因为初始化的源码文件部分所涵盖的内容很多包括创建渲染、更新渲染、Fiber树的创建与diffelement的创建与插入还包括一些优化算法所以我就整个的React执行流程画了一个简单的示意图。 React源码执行流程图 从图中我们很清晰的看到ReactDOM.render()之后我们的组件具体干了什么事情那么我们进入源码文件一探究竟吧。 // packages/react-dom/src/client/ReactDOMLegacy.js export function render(element: React$Elementany, // 经过babel解析后的elementcontainer: Container, // 根组件节点 document.getElementById(root)..callback: ?Function,// 回调 ) {// 做合法容器的验证(根组件)invariant(isValidContainer(container),Target container is not a DOM element.,);// 开发模式下if (__DEV__) {const isModernRoot isContainerMarkedAsRoot(container) container._reactRootContainer undefined;if (isModernRoot) {console.error(You are calling ReactDOM.render() on a container that was previously passed to ReactDOM.createRoot(). This is not supported. Did you mean to call root.render(element)?,);}}// 返回 legacyRenderSubtreeIntoContainerreturn legacyRenderSubtreeIntoContainer(null,element,container,false,callback,); }所以当前render函数仅仅只是做了部分逻辑阅读React源码给你一个直观的感受就是他拆分的颗粒度非常的细很多重复命名的函数可能是见名知意的变量名只有那么几个常见的组合吧这也是React作者的用心良苦吧。 追根究底我们还是得看一看legacyRenderSubtreeIntoContainer究竟干了些不为人知的事情呢 legacyRenderSubtreeIntoContainer function legacyRenderSubtreeIntoContainer(parentComponent: ?React$Componentany, any, // 父级组件children: ReactNodeList, // 当前元素container: Container, // 容器 eggetElementById(root)forceHydrate: boolean, callback: ?Function, ) {if (__DEV__) {topLevelUpdateWarnings(container);warnOnInvalidCallback(callback undefined ? null : callback, render);}// TODO: Without any type, Flow says Property cannot be accessed on any// member of intersection type. Whyyyyyy.let root: RootType (container._reactRootContainer: any);let fiberRoot;// 如果有根组件表示不是初始化渲染则走下面的批量更新// 没有根组件那么就要去创建根组件了if (!root) {// 初始化挂载root container._reactRootContainer legacyCreateRootFromDOMContainer(container,forceHydrate,);fiberRoot root._internalRoot;if (typeof callback function) {const originalCallback callback;callback function() {const instance getPublicRootInstance(fiberRoot);originalCallback.call(instance);};}// 不必要的批量更新unbatchedUpdates(() {updateContainer(children, fiberRoot, parentComponent, callback);});} else {fiberRoot root._internalRoot;if (typeof callback function) {const originalCallback callback;callback function() {const instance getPublicRootInstance(fiberRoot);originalCallback.call(instance);};}// 批量更新updateContainer(children, fiberRoot, parentComponent, callback);}return getPublicRootInstance(fiberRoot); }有根节点的情况下我们判定为非首次渲染状态执行updateContainer没有根节点的情况下我们判定为首次渲染接着去创建根节点执行legacyCreateRootFromDOMContainer拿到了root之后我们会去触发执行updateContainer legacyCreateRootFromDOMContainer function legacyCreateRootFromDOMContainer(container: Container, // 容器forceHydrate: boolean, // value:false ): RootType {const shouldHydrate forceHydrate || shouldHydrateDueToLegacyHeuristic(container);// First clear any existing content.if (!shouldHydrate) {let warned false;let rootSibling;while ((rootSibling container.lastChild)) {if (__DEV__) {if (!warned rootSibling.nodeType ELEMENT_NODE (rootSibling: any).hasAttribute(ROOT_ATTRIBUTE_NAME)) {warned true;console.error(render(): Target node has markup rendered by React, but there are unrelated nodes as well. This is most commonly caused by white-space inserted around server-rendered markup.,);}}container.removeChild(rootSibling);}}if (__DEV__) {if (shouldHydrate !forceHydrate !warnedAboutHydrateAPI) {warnedAboutHydrateAPI true;console.warn(render(): Calling ReactDOM.render() to hydrate server-rendered markup will stop working in React v18. Replace the ReactDOM.render() call with ReactDOM.hydrate() if you want React to attach to the server HTML.,);}}// 关注createLegacyRootreturn createLegacyRoot(container,shouldHydrate? {hydrate: true,}: undefined,); }createLegacyRoot export function createLegacyRoot(container: Container, // 容器options?: RootOptions, ): RootType {//关注ReactDOMBlockingRootreturn new ReactDOMBlockingRoot(container, LegacyRoot, options); }ReactDOMBlockingRoot function ReactDOMBlockingRoot(container: Container, // 容器tag: RootTag, // LegacyRoot 0;BlockingRoot 1;ConcurrentRoot 2;options: void | RootOptions, ) {this._internalRoot createRootImpl(container, tag, options); }我们在这里看到this._internalRoot出来了因为在先前这个值会给到fiberRoot所以我们再去看一看这个_internalRoot是怎么创建出来的 createRootImpl function createRootImpl(container: Container, tag: RootTag, options: void | RootOptions, ) {// Tag is either LegacyRoot or Concurrent Rootconst hydrate options ! null options.hydrate true;const hydrationCallbacks (options ! null options.hydrationOptions) || null;const mutableSources (options ! null options.hydrationOptions ! null options.hydrationOptions.mutableSources) ||null;// 关注createContainerconst root createContainer(container, tag, hydrate, hydrationCallbacks);markContainerAsRoot(root.current, container);const containerNodeType container.nodeType;if (enableEagerRootListeners) {const rootContainerElement container.nodeType COMMENT_NODE ? container.parentNode : container;listenToAllSupportedEvents(rootContainerElement);} else {if (hydrate tag ! LegacyRoot) {const doc containerNodeType DOCUMENT_NODE? container: container.ownerDocument;// We need to cast this because Flow doesnt work// with the hoisted containerNodeType. If we inline// it, then Flow doesnt complain. We intentionally// hoist it to reduce code-size.eagerlyTrapReplayableEvents(container, ((doc: any): Document));} else if (containerNodeType ! DOCUMENT_FRAGMENT_NODE containerNodeType ! DOCUMENT_NODE) {ensureListeningTo(container, onMouseEnter, null);}}if (mutableSources) {for (let i 0; i mutableSources.length; i) {const mutableSource mutableSources[i];registerMutableSourceForHydration(root, mutableSource);}}// 关注rootreturn root; }相关参考视频讲解进入学习 见名知意关注createContainer为创建容器看其源码 createContainer // packages/react-reconciler/src/ReactFiberReconciler.old.js export function createContainer(containerInfo: Container, // 容器tag: RootTag, // LegacyRoot 0;BlockingRoot 1;ConcurrentRoot 2;hydrate: boolean, hydrationCallbacks: null | SuspenseHydrationCallbacks, ): OpaqueRoot {// 关注createFiberRootreturn createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks); }createFiberRoot export function createFiberRoot(containerInfo: any, tag: RootTag, hydrate: boolean, hydrationCallbacks: null | SuspenseHydrationCallbacks, ): FiberRoot {const root: FiberRoot (new FiberRootNode(containerInfo, tag, hydrate): any);if (enableSuspenseCallback) {root.hydrationCallbacks hydrationCallbacks;}// 关注createHostRootFiberconst uninitializedFiber createHostRootFiber(tag);root.current uninitializedFiber;uninitializedFiber.stateNode root;// 初始化更新队列initializeUpdateQueue(uninitializedFiber);return root; }关注 root.current、uninitializedFiber.stateNode这两个玩意儿后面有大作用我们还是看看createHostRootFiber吧 createHostRootFiber export function createHostRootFiber(tag: RootTag): Fiber {let mode;if (tag ConcurrentRoot) {mode ConcurrentMode | BlockingMode | StrictMode;} else if (tag BlockingRoot) {mode BlockingMode | StrictMode;} else {mode NoMode;}if (enableProfilerTimer isDevToolsPresent) {// Always collect profile timings when DevTools are present.// This enables DevTools to start capturing timing at any point–// Without some nodes in the tree having empty base times.mode | ProfileMode;}return createFiber(HostRoot, null, null, mode); }一眼望去这里便是对tag的处理到了后面便是去创建fiber节点 createFiber const createFiber function(tag: WorkTag, pendingProps: mixed, key: null | string, mode: TypeOfMode, ): Fiber {// $FlowFixMe: the shapes are exact here but Flow doesnt like constructorsreturn new FiberNode(tag, pendingProps, key, mode); };那么主角出来了就是我们的FiberNode这里才走完初始化的创建流程 所以大致的流程就是上面的图里画的那样子创建流程我们就告一段落那我们再去看看更新的流程是怎么玩的。 我们知道除了ReactDOM.render()会触发更新流程之外我们还有setState、强制更新、hooks里面的setXxxx等等手段可以触发更新所谓setState那么不正好是我们Component原型上挂的方法嘛。我们回顾一下Component那些更新都是调用了updater触发器上的方法那么我们去看一下这个东西。 const classComponentUpdater {isMounted,// setStateenqueueSetState(inst, payload, callback) {const fiber getInstance(inst);const eventTime requestEventTime(); // 获取更新触发的时间const lane requestUpdateLane(fiber); // 获取任务优先级//根据更新触发时间 更新优先级来创建更新任务对象const update createUpdate(eventTime, lane); // 创建更新任务对象// const update: Update* {// eventTime, // 更新时间// lane, // 优先级// tag: UpdateState, // 更新类型0更新1替换。2强制替换3捕获型更新// payload: null,// 需要更新的内容// callback: null, // 更新完后的回调// next: null, // 指向下一个更新// };// 把内容填上update.payload payload;if (callback ! undefined callback ! null) {if (__DEV__) {// 开发环境下腰给个警告warnOnInvalidCallback(callback, setState);}// 如果有回调那么加上回调update.callback callback;}// const update: Update* {// eventTime, // 更新时间 you// lane, // 优先级 you // tag: UpdateState, // 更新类型0更新1替换。2强制替换3捕获型更新// payload: null,// 需要更新的内容 you// callback: null, // 更新完后的回调 you// next: null, // 指向下一个更新// };enqueueUpdate(fiber, update);// 推入更新队列scheduleUpdateOnFiber(fiber, lane, eventTime);// 调度if (__DEV__) {if (enableDebugTracing) {if (fiber.mode DebugTracingMode) {const name getComponentName(fiber.type) || Unknown;logStateUpdateScheduled(name, lane, payload);}}}if (enableSchedulingProfiler) {markStateUpdateScheduled(fiber, lane);}},// replaceStateenqueueReplaceState(inst, payload, callback) {const fiber getInstance(inst);const eventTime requestEventTime();const lane requestUpdateLane(fiber);const update createUpdate(eventTime, lane);update.tag ReplaceState;update.payload payload;if (callback ! undefined callback ! null) {if (__DEV__) {warnOnInvalidCallback(callback, replaceState);}update.callback callback;}enqueueUpdate(fiber, update);scheduleUpdateOnFiber(fiber, lane, eventTime);if (__DEV__) {if (enableDebugTracing) {if (fiber.mode DebugTracingMode) {const name getComponentName(fiber.type) || Unknown;logStateUpdateScheduled(name, lane, payload);}}}if (enableSchedulingProfiler) {markStateUpdateScheduled(fiber, lane);}},// forceUpdateenqueueForceUpdate(inst, callback) {const fiber getInstance(inst);const eventTime requestEventTime();const lane requestUpdateLane(fiber);const update createUpdate(eventTime, lane);update.tag ForceUpdate;if (callback ! undefined callback ! null) {if (__DEV__) {warnOnInvalidCallback(callback, forceUpdate);}update.callback callback;}enqueueUpdate(fiber, update);scheduleUpdateOnFiber(fiber, lane, eventTime);if (__DEV__) {if (enableDebugTracing) {if (fiber.mode DebugTracingMode) {const name getComponentName(fiber.type) || Unknown;logForceUpdateScheduled(name, lane);}}}if (enableSchedulingProfiler) {markForceUpdateScheduled(fiber, lane);}}, };updateContainer export function updateContainer(element: ReactNodeList, container: OpaqueRoot, parentComponent: ?React$Componentany, any, callback: ?Function, ): Lane {if (__DEV__) {onScheduleRoot(container, element);}const current container.current;const eventTime requestEventTime();if (__DEV__) {// $FlowExpectedError - jest isnt a global, and isnt recognized outside of testsif (undefined ! typeof jest) {warnIfUnmockedScheduler(current);warnIfNotScopedWithMatchingAct(current);}}const lane requestUpdateLane(current);if (enableSchedulingProfiler) {markRenderScheduled(lane);}const context getContextForSubtree(parentComponent);if (container.context null) {container.context context;} else {container.pendingContext context;}if (__DEV__) {if (ReactCurrentFiberIsRendering ReactCurrentFiberCurrent ! null !didWarnAboutNestedUpdates) {didWarnAboutNestedUpdates true;console.error(Render methods should be a pure function of props and state; triggering nested component updates from render is not allowed. If necessary, trigger nested updates in componentDidUpdate.\n\n Check the render method of %s.,getComponentName(ReactCurrentFiberCurrent.type) || Unknown,);}}const update createUpdate(eventTime, lane);// 创建更新任务// Caution: React DevTools currently depends on this property// being called element.update.payload {element};callback callback undefined ? null : callback;if (callback ! null) {if (__DEV__) {if (typeof callback ! function) {console.error(render(...): Expected the last optional callback argument to be a function. Instead received: %s.,callback,);}}update.callback callback;}enqueueUpdate(current, update); // 推入更新队列scheduleUpdateOnFiber(current, lane, eventTime); // 进行调度return lane; }我们看到了enqueueSetState、enqueueReplaceState、enqueueForceUpdate还是初始化时候走的updateContainer都是走了几乎一样的逻辑requestEventTime requestUpdateLane createUpdate enqueueUpdate scheduleUpdateOnFiber 总结 本章从ReactDOM.render()开始讲解了初始化的时候根节点的创建与更新流程以及在类组件原型上挂载的一些更新的方法但是为什么这一章不直接把他更新流程讲完呢因为下一章要讲一下fiberNode这个东西简而言之他只是一个架构概念并不是React独有的但是现在很有必要一起来看一看这个那么下一章我们来一起揭开FiberNode的神秘面纱吧
http://www.dnsts.com.cn/news/211489.html

相关文章:

  • 顺德网站建设制作延安有哪些做网站的公司
  • 比较好的营销网站简历制作官网
  • 网站建设竞争对手分析哪些网站百度不收录
  • 网站点击快速排名设计网页设计师培训
  • 那个网站做苗木鞍山58招聘
  • 免费网站源码模板下载凉山网站开发
  • seo如何提高网站排名html网站的设计
  • 有中文网站 怎么做英文网站滨州网站建设公司
  • 蒙牛网站建设佛山手机网站建设
  • 做网站有什么js特效单页购物网站源码
  • 好看的食品网站wordpress页面标题字号
  • 建湖县建设局网站品牌线上营销策划
  • 垂直网站怎么下载app到手机上
  • 企业官网建站教育网站建设收费
  • wordpress 站内消息wp建站系统
  • 珠海做网站多少钱平面设计速成班
  • 如何提升网站的搜索排名软件公司门户网站模板
  • 中国建设信息港网站黑五手表网站
  • 直播网站模板php旅游类网站开发毕业设计
  • 自己开发一个手机网站上海做网站公司
  • 徐州市制作网站的公司品牌logo
  • 合肥建设学校官网网站网站制作怎么做语音搜索框
  • 青岛建设监理协会网站怎么玩互联网能赚钱
  • 高端网站的建设大连网站设计九即问仟亿科技
  • 个人备案做公司网站怎么设置域名
  • 湖北省住房和城乡建设厅官方网站优化师证书
  • 做微信推文的网站用tp框架怎么做网站
  • 做玻璃瓶的网站福州网站制作有限公司
  • 网站建设类型分类青海省交通建设管理局网站
  • 网站懒加载怎么做网站查询器