尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
react源码学习笔记
1、virtual domReactNode分为以下几类React$Element其属性有export type ReactElement { $$typeof: any, type: any, key: any, ref: any, props: any, // __DEV__ or for string refs _owner: any, // __DEV__ _store: {validated: 0 | 1 | 2, ...}, // 0: not validated, 1: validated, 2: force fail _debugInfo: null | ReactDebugInfo, _debugStack: Error, _debugTask: null | ConsoleTask, };type支持的类型有functionstringREACT_ACTIVITY_TYPEREACT_FRAGMENT_TYPEREACT_STRICT_MODE_TYPEREACT_PROFILER_TYPEREACT_SUSPENSE_TYPEREACT_SUSPENSE_LIST_TYPEREACT_LEGACY_HIDDEN_TYPEREACT_VIEW_TRANSITION_TYPEREACT_SCOPE_TYPEREACT_TRACING_MARKER_TYPEobject。当类型是object时其属性$$typeof可能值为REACT_CONTEXT_TYPEREACT_CONSUMER_TYPEREACT_FORWARD_REF_TYPEREACT_MEMO_TYPEREACT_LAZY_TYPEReactPortalReactTextReactFragment2、react接口其暴露接口有export { Children{ map, forEach, count, toArray, only }, createMutableSource, createRef, Component, PureComponent, createContext, forwardRef, lazy, memo, useCallback, useContext, useEffect, useImperativeHandle, useDebugValue, useLayoutEffect, useMemo, useMutableSource, useReducer, useRef, useState, REACT_FRAGMENT_TYPE as Fragment, REACT_PROFILER_TYPE as Profiler, REACT_STRICT_MODE_TYPE as StrictMode, REACT_DEBUG_TRACING_MODE_TYPE as unstable_DebugTracingMode, REACT_SUSPENSE_TYPE as Suspense, createElement__DEV__ ? createElementWithValidation : createElementProd, cloneElement__DEV__ ? cloneElementWithValidation : cloneElementProd, isValidElement, ReactVersion as version, ReactSharedInternals as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, // Deprecated behind disableCreateFactory createFactory__DEV__ ? createFactoryWithValidation : createFactoryProd, // Concurrent Mode useTransition, startTransition, useDeferredValue, REACT_SUSPENSE_LIST_TYPE as SuspenseList, REACT_LEGACY_HIDDEN_TYPE as unstable_LegacyHidden, getCacheForType as unstable_getCacheForType, useCacheRefresh as unstable_useCacheRefresh, REACT_CACHE_TYPE as unstable_Cache, // enableScopeAPI REACT_SCOPE_TYPE as unstable_Scope, useOpaqueIdentifier as unstable_useOpaqueIdentifier, };Component和PureComponent定义在ReactBaseClasses.js中。Component定义如下function Component(props, context, updater) { this.props props; this.context context; // If a component has string refs, we will assign a different object later. this.refs emptyObject; // We initialize the default updater but the real one gets injected by the // renderer. this.updater updater || ReactNoopUpdateQueue; } Component.prototype.isReactComponent {}; Component.prototype.setState function(partialState, callback) { invariant( 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., ); this.updater.enqueueSetState(this, partialState, callback, setState); }; Component.prototype.forceUpdate function(callback) { this.updater.enqueueForceUpdate(this, callback, forceUpdate); };PureComponent定义为function PureComponent(props, context, updater) { this.props props; this.context context; // If a component has string refs, we will assign a different object later. this.refs emptyObject; this.updater updater || ReactNoopUpdateQueue; } const pureComponentPrototype (PureComponent.prototype new ComponentDummy()); pureComponentPrototype.constructor PureComponent; // Avoid an extra prototype jump for these methods. Object.assign(pureComponentPrototype, Component.prototype); pureComponentPrototype.isPureReactComponent true;3、源码解析3.1 ReactDOM.render调用的是ReactDOMLegacy.js中的render。创建reactRoot第一次挂载时采用非批量更新。export function render( element: React$Elementany, container: Container, callback: ?Function, ) { return legacyRenderSubtreeIntoContainer( null, element, container, false, callback, ); } function legacyRenderSubtreeIntoContainer( parentComponent: ?React$Componentany, any, children: ReactNodeList, container: Container, forceHydrate: boolean, callback: ?Function, ) { let root container._reactRootContainer; let fiberRoot: FiberRoot; if (!root) { // Initial mount 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); }; } // Initial mount should not be batched. 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); }; } // Update updateContainer(children, fiberRoot, parentComponent, callback); } return getPublicRootInstance(fiberRoot); }创建reactRoot是通过调用legacyCreateRootFromDOMContainer最终是调用ReactFiberReconciler.js中的createContainer来创建FiberRoot。function legacyCreateRootFromDOMContainer( container: Container, forceHydrate: boolean, ): RootType { // First clear any existing content. if (!forceHydrate) { let rootSibling; while ((rootSibling container.lastChild)) { container.removeChild(rootSibling); } } return createLegacyRoot( container, forceHydrate ? { hydrate: true, } : undefined, ); } export function createLegacyRoot( container: Container, options?: RootOptions, ): RootType { return new ReactDOMLegacyRoot(container, options); } function ReactDOMLegacyRoot(container: Container, options: void | RootOptions) { this._internalRoot createRootImpl(container, LegacyRoot, options); } function createRootImpl( container: Container, tag: RootTag, options: void | RootOptions, ) { // Tag is either LegacyRoot or Concurrent Root const hydrate options ! null options.hydrate true; const hydrationCallbacks (options ! null options.hydrationOptions) || null; const mutableSources (options ! null options.hydrationOptions ! null options.hydrationOptions.mutableSources) || null; const isStrictMode options ! null options.unstable_strictMode true; let concurrentUpdatesByDefaultOverride null; if (allowConcurrentByDefault) { concurrentUpdatesByDefaultOverride options ! null options.unstable_concurrentUpdatesByDefault ! null ? options.unstable_concurrentUpdatesByDefault : null; } const root createContainer( container, tag, hydrate, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, ); markContainerAsRoot(root.current, container); const rootContainerElement container.nodeType COMMENT_NODE ? container.parentNode : container; listenToAllSupportedEvents(rootContainerElement); if (mutableSources) { for (let i 0; i mutableSources.length; i) { const mutableSource mutableSources[i]; registerMutableSourceForHydration(root, mutableSource); } } return root; } export function createContainer( containerInfo: Container, tag: RootTag, hydrate: boolean, hydrationCallbacks: null | SuspenseHydrationCallbacks, isStrictMode: boolean, concurrentUpdatesByDefaultOverride: null | boolean, ): OpaqueRoot { return createFiberRoot( containerInfo, tag, hydrate, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, ); } export function createFiberRoot( containerInfo: any, tag: RootTag, hydrate: boolean, hydrationCallbacks: null | SuspenseHydrationCallbacks, isStrictMode: boolean, concurrentUpdatesByDefaultOverride: null | boolean, ): FiberRoot { const root: FiberRoot (new FiberRootNode(containerInfo, tag, hydrate): any); if (enableSuspenseCallback) { root.hydrationCallbacks hydrationCallbacks; } // Cyclic construction. This cheats the type system right now because // stateNode is any. const uninitializedFiber createHostRootFiber( tag, isStrictMode, concurrentUpdatesByDefaultOverride, ); root.current uninitializedFiber; uninitializedFiber.stateNode root; if (enableCache) { const initialCache new Map(); root.pooledCache initialCache; const initialState { element: null, cache: initialCache, }; uninitializedFiber.memoizedState initialState; } else { const initialState { element: null, }; uninitializedFiber.memoizedState initialState; } initializeUpdateQueue(uninitializedFiber); return root; }3.2 ReactDOM.createRootcreateRoot创建的类型为ReactDOMRoot成员有_internalRoot(类型为FiberRoot是通过createContainer创建)FiberRoot与Fiber关系为其有两个方法renderReactDOMRoot.prototype.render function (children: ReactNodeList): void { const root this._internalRoot; if (root null) { throw new Error(Cannot update an unmounted root.); } updateContainer(children, root, null, null); }; export function updateContainer( element: ReactNodeList, container: OpaqueRoot, parentComponent: ?component(...props: any), callback: ?Function, ): Lane { const current container.current; const lane requestUpdateLane(current); updateContainerImpl( current, lane, element, container, parentComponent, callback, ); return lane; }unmount3.3 React-reconcilerDispatcher作为hooks的关键实现其定义为export type Dispatcher { use: T(UsableT) T, readContextT(context: ReactContextT): T, useStateS(initialState: (() S) | S): [S, DispatchBasicStateActionS], useReducerS, I, A( reducer: (S, A) S, initialArg: I, init?: (I) S, ): [S, DispatchA], useContextT(context: ReactContextT): T, useRefT(initialValue: T): {current: T}, useEffect( create: () (() void) | void, deps: Arraymixed | void | null, ): void, useEffectEvent: Args, F: (...ArrayArgs) mixed(callback: F) F, useInsertionEffect( create: () (() void) | void, deps: Arraymixed | void | null, ): void, useLayoutEffect( create: () (() void) | void, deps: Arraymixed | void | null, ): void, useCallbackT(callback: T, deps: Arraymixed | void | null): T, useMemoT(nextCreate: () T, deps: Arraymixed | void | null): T, useImperativeHandleT( ref: {current: T | null} | ((inst: T | null) mixed) | null | void, create: () T, deps: Arraymixed | void | null, ): void, useDebugValueT(value: T, formatterFn: ?(value: T) mixed): void, useDeferredValueT(value: T, initialValue?: T): T, useTransition(): [ boolean, (callback: () void, options?: StartTransitionOptions) void, ], useSyncExternalStoreT( subscribe: (() void) () void, getSnapshot: () T, getServerSnapshot?: () T, ): T, useId(): string, useCacheRefresh: () T(?() T, ?T) void, useMemoCache: (size: number) Arrayany, useHostTransitionStatus: () TransitionStatus, useOptimistic: S, A( passthrough: S, reducer: ?(S, A) S, ) [S, (A) void], useFormState: S, P( action: (AwaitedS, P) S, initialState: AwaitedS, permalink?: string, ) [AwaitedS, (P) void, boolean], useActionState: S, P( action: (AwaitedS, P) S, initialState: AwaitedS, permalink?: string, ) [AwaitedS, (P) void, boolean], };Dispatcher实例有ContextOnlyDispatcherHooksDispatcherOnMountHooksDispatcherOnUpdateHooksDispatcherOnRerenderReact Fiber架构将Commit阶段拆分为三个子阶段commitRootcommitBeforeMutationEffectscommitMutationEffectscommitLayoutEffects3.3.1 updateContainer内部调用scheduleUpdateOnFiber会区分同步调用还是异步调用(基于时间片或者优先级)调用ensureRootIsScheduled其会将root添加到由firstScheduledRoot和lastScheduledRoot组成的调度链表中使用Scheduler_scheduleCallback触发调用processRootScheduleInImmediateTask即从链表中取出调度root处理其会区分是否支持微任务支持微任务时调用processRootScheduleInImmediateTask或者processRootScheduleInMicrotask不支持情况调用processRootScheduleInImmediateTask。在processRootScheduleInMicrotask中会调用scheduleTaskForRootDuringMicrotask其内部调用performWorkOnRootViaSchedulerTask调用performWorkOnRoot。在performWorkOnRoot中会区分调用renderRootConcurrent并发渲染workLoopConcurrentworkLoopConcurrentBySchedulerrenderRootSync同步渲染workLoopSync在workLoopConcurrentworkLoopConcurrentByScheduler或者workLoopSync都会调用performUnitOfWorkperformUnitOfWork会调用beginWorkbeginWork会区分组件类型类组件还是函数组件对于类组件会调用 updateClassComponentupdateClassComponent在更新过程中会先调用nextChildren instance.render();然后调用reconcileChildren(current, workInProgress, nextChildren, renderLanes);同步调用flushSyncWorkOnLegacyRootsOnly3.4 createElement根据类型配置属性以及子节点创建ReactElement。由编译期Babel 把 JSX 编译成React.createElement()export function createElement(type, config, children) { let propName; // Reserved names are extracted const props {}; let key null; if (config ! null) { if (hasValidKey(config)) { if (enableOptimisticKey config.key REACT_OPTIMISTIC_KEY) { key REACT_OPTIMISTIC_KEY; } else { key config.key; } } // Remaining properties are added to a new props object for (propName in config) { if ( hasOwnProperty.call(config, propName) // Skip over reserved prop names propName ! key // Even though we dont use these anymore in the runtime, we dont want // them to appear as props, so in createElement we filter them out. // We dont have to do this in the jsx() runtime because the jsx() // transform never passed these as props; it used separate arguments. propName ! __self propName ! __source ) { props[propName] config[propName]; } } } // Children can be more than one argument, and those are transferred onto // the newly allocated props object. const childrenLength arguments.length - 2; if (childrenLength 1) { props.children children; } else if (childrenLength 1) { const childArray Array(childrenLength); for (let i 0; i childrenLength; i) { childArray[i] arguments[i 2]; } props.children childArray; } // Resolve default props if (type type.defaultProps) { const defaultProps type.defaultProps; for (propName in defaultProps) { if (props[propName] undefined) { props[propName] defaultProps[propName]; } } } const trackActualOwner __DEV__ ReactSharedInternals.recentlyCreatedOwnerStacks ownerStackLimit; let debugStackDEV false; return ReactElement( type, key, props, getOwner(), debugStackDEV, __DEV__ (trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask), ); } function ReactElement(type, key, props, owner, debugStack, debugTask) { // Ignore whatever was passed as the ref argument and treat props.ref as // the source of truth. The only thing we use this for is element.ref, // which will log a deprecation warning on access. In the next release, we // can remove element.ref as well as the ref argument. const refProp props.ref; // An undefined element.ref is coerced to null for // backwards compatibility. const ref refProp ! undefined ? refProp : null; let element; { // In prod, ref is a regular property and _owner doesnt exist. element { // This tag allows us to uniquely identify this as a React Element $$typeof: REACT_ELEMENT_TYPE, // Built-in properties that belong on the element type, key, ref, props, }; } return element; }3.5 contextchildContextTypes和contextTypes是React 旧版 Context APILegacy Context中的一对核心属性用于实现跨组件层级的数据传递。它们必须配合使用但职责完全不同childContextTypes定义在提供者父组件上声明getChildContext()返回的 context 对象中每个属性的类型。contextTypes定义在消费者子/后代组件上声明该组件希望从 context 中读取哪些属性
RELATED

相关推荐

Cartographer实战指南:环境配置、TF坐标系与建图参数调优

Cartographer实战指南:环境配置、TF坐标系与建图参数调优

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/10/14 1:39:56
高清摄像机测试方法详解:从MTF50到动态范围的工程化验证

高清摄像机测试方法详解:从MTF50到动态范围的工程化验证

简介:《高清摄像机测试方法》是一份面向安防监控、视频设备研发与质检人员的高清摄像机性能评估资料,源自公共安全行业标准征求意见稿,系统解决了测试条件、测量仪器和量化指标不统一的问题。压缩包内为单个DOC文档,体积约1.37MB&…

📅 2026/10/14 1:39:56
告别 API 费用:Ollama 本地部署大模型完整指南(从安装到代码调用一篇通)

告别 API 费用:Ollama 本地部署大模型完整指南(从安装到代码调用一篇通)

摘要:本文手把手教你用 Ollama 在本地电脑上跑大模型,全程不花一分钱 API 费、断网也能用、数据完全不出本机。内容覆盖三个平台的安装、模型选择、命令行操作、三种代码调用方式(原生 REST API、OpenAI SDK 兼容、流式输出)&…

📅 2026/10/14 1:39:56
MORE NEWS

更多资讯

📰

如何在windows11禁止ollama开机启动

如何在windows11禁止ollama开机启动 在 Windows 11 上禁止 Ollama 开机自动启动,操作起来并不复杂。由于 Ollama 安装后默认会设置开机自启,但并没有提供直接的图形化开关,因此我们需要通过系统自带的功能来管理它。 删除启动文件夹快捷方式 …

📰

Kali Linux入门必看:3天速成网络安全基础,小白也能轻松上手!收藏起来学!

Kali Linux入门必看:3天速成网络安全基础,小白也能轻松上手!收藏起来学! 本文针对网络安全初学者在Kali Linux上遇到的常见问题,如安装、命令理解、工具使用等,提供了实用的入门指南。文章强调初学者无需一…

📰

SQL注入实战:低权限服务账户下如何以内网跳板实现C2上线(收藏必备)

SQL注入实战:低权限服务账户下如何以内网跳板实现C2上线(收藏必备) 本文通过实战案例,展示了在MSSQL注入中,当xp_cmdshell仅以低权限服务账户执行时,如何利用注入点作为内网跳板。通过堆叠查询&#xff0c…

📰

2026年AI安全上市公司梳理:产品、认证与商业化进展

随着大模型和智能体逐步进入企业业务流程,网络安全企业面临两类新需求:一是防范提示词注入、敏感数据泄露、模型输出风险等AI应用安全问题;二是利用AI提升威胁分析、告警研判和安全运营效率。因此,分析网络安全AI概念股&#xff0…

📰

PLC数据处理指令详解:从传送比较到移位转换的实战应用

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

DeepSeek私有化部署全攻略:SpringBoot集成与语音图片交互实战

最近一直在折腾大模型私有化部署这件事,从年初开始陆续把几个开源模型搬到内网试过,踩了不少坑,也总结出一套比较顺手的链路。这篇就完整聊聊“私有化部署DeepSeek SpringBoot集成 带语音和图片的UI交互”整条路线,给正准备把大…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬