Skip to main content

React Inside

  • React
    • 定义各种元素类型
    • 定义上下文、状态规则
  • ReactDOM
    • 按约定渲染各种元素类型
    • 事件 - 状态
  • jsx - ReactElement
    • Fragment
    • jsx (Runtime) -> jsxWithValidationDynamic
      • 校验 type
      • 校验 children
      • 校验 children key
      • 校验属性
        • Fragment 只允许 children 和 key, 不允许存在 ref
        • propTypes 校验
    • jsxs (Static) -> jsxWithValidationStatic
      • children 为数组
    • Prod 环境 jsx=jsxs,且没有校验
    • 保留属性
      • ref
      • key - 会转为 string
      • __self - 辅助判断 this != owner
      • __source - 转译时添加的辅助信息
  • 新的 jsx 避免 spread key
  • Feature
    • ScopeAPI
    • DebugTracing
    • TransitionTracing
    • SymbolFallbackForWWW
    • LazyContextPropagation
    • SuspenseAvoidThisFallback
    • SuspenseAvoidThisFallbackFizz
    • LegacyHidden
    • UseRefAccessWarning
    • StrictMode
      • createRootStrictEffectsByDefault
    • 实验
      • Cache
      • CacheElement
      • CPUSuspense
  • API - React
    • Component
    • PureComponent - 没有 setStateforceUpdate 方法
    • memo
    • 创建
      • createElement(type,props,children)
      • createFactory(type)
    • 转换
      • cloneElement(element, config, children)
        • 会应用 defaultProps 到 props
        • 会复制 children
      • isValidElement()
        • $$typeof === REACT_ELEMENT_TYPE
      • Children
    • Fragment
    • createRef
    • forwardRef
    • lazy, Suspense
    • startTransition, useTransition
    • Hooks - 由 ReactCurrentDispatcher.current Dispatcher 处理 - 在 FC 渲染时设置
      • Basic - useState, useEffect, useContext
      • Additional - useReducer, useCallback, useMemo, useRef, useImperativeHandle, useDebugValue
        • useLayoutEffect = useEffect
          • DOM 操作后执行 - componentDidMount, componentDidUpdate
        • useDeferredValue - 低优先级
          • 类似于 debounce
        • const [isPending,startTransition]=useTransition()
          • Transition - 相对不那么着急更新的状态,耗时比较久的状态
          • 用户基于已经更新的状态进行交互
        • useId - 生成唯一 ID
      • Library
        • useSyncExternalStore
          • const state = useSyncExternalStore(subscribe, getSnapshot[, getServerSnapshot])
          • 同步外部存储 - 例如 zustand
        • useInsertionEffect = useEffect
          • DOM 操作之前执行 - 用于 css-in-js 库
  • 模块
    • react-is - 类型判断
    • react-reconciler - 用于实现自定义渲染
    • react-refresh - bundlers 集成 fast refresh
    • scheduler - 堆、优先级队列
    • shared
    • use-subscription
    • use-sync-external-store
    • Experimental
      • react-server - react-server-{dom-relay,dom-webpack,native-relay}
      • react-pg
      • react-cache
      • react-client - consuming React streaming models
      • react-fetch
      • react-fs - for react-server - experimental - bindings for the filesystem
// React 相关 Symbol - react.<nname>
// portal,fragment,provider,context,forward_ref,suspense,suspense_list
// memo,lazy,scope
// offscreen
// legacy_hidden
// cache
// tracing_marker
// default_value
// strick_mode,profiler,debug_trace_mode
// server_context
const REACT_ELEMENT_TYPE = Symbol.for('react.element');

const ReactElement = (type, key, ref, self, source, owner, props) => {
return {
// 类型识别
$$typeof: REACT_ELEMENT_TYPE,

// Built-in properties that belong on the element
type: type,
key: key,
ref: ref,
props: props, // dev 时 Object.freeze

// 创建该元素的组件
_owner: owner,

// dev 相关属性
_store: { validated: false },
_self: self,
_source: source,
};
};

function jsx(type, config, maybeKey, source, self) {
const { key, ref, __self, __source, ...props } = config;
return ReactElement(
type,
maybeKey || key || undefined,
ref,
// dev only
source,
self,
//
ReactCurrentOwner.current,
props,
);
}

const lazy = (ctor) => {
return {
$$typeof: REACT_LAZY_TYPE,
// Uninitialized -> Pending -> Resolved, Rejected
_payload: { _status: Uninitialized, _result: ctor },
// 会维护 _payload
// 非 Resolved 会 throw payload._result
_init: lazyInitializer,
};
};

const forwardRef = (render) => {
return { $$typeof: REACT_FORWARD_REF_TYPE, render };
};

const memo = (type: React$ElementType, compare?) => {
return {
$$typeof: REACT_MEMO_TYPE,
type,
compare: compare === undefined ? null : compare,
};
};

const createContext = (defaultValue) => {
const context = {
$$typeof: REACT_CONTEXT_TYPE,
_currentValue: defaultValue,
_currentValue2: defaultValue,
_threadCount: 0,
// These are circular
Provider: null,
Consumer: null,

// Add these to use same hidden class in VM as ServerContext
_defaultValue: null,
_globalName: null,
};
context.Provider = {
$$typeof: REACT_PROVIDER_TYPE,
_context: context,
};
context.Consumer = context;
return context;
};

class Component {
refs = {};
constructor(props, context, updater);

isReactComponent = {};
setState(partialState, callback) {
this.updater.enqueueSetState(this, partialState, callback, 'setState');
}
forceUpdate(callback) {
this.updater.enqueueForceUpdate(this, callback, 'forceUpdate');
}
}

Fiber

  • 工作单位
  • 两个阶段
    • render - 异步、优先级、可中断、beginWork
    • commit - 同步、commitWork
      • WIP tree -> current tree
  • 支持 HMR 能力 - Function, Class, ForwardRef
  • 复用 ReactElement 的 type 和 key
  • createFiberFromXyz
  • createFiberFromTypeAndProps
    • Fragment, Profiler, Suspense, SuspenseList, Offscreen, LegacyHidden
    • Scope, Cache
    • TracingMarker
    • MemoComponent, LazyComponent
    • ContextProvider, ContextConsumer
    • HostComponent
    • ClassComponent
  • beginWork
  • HooksDispatcherOnMount - 第一次 无状态时
  • HooksDispatcherOnUpdate - 存在之前状态时
  • Lanes - 不同优先级队列
    • SyncLane
    • InputContinuousHydrationLane
    • InputContinuousLane
    • DefaultHydrationLane
    • DefaultLane
    • TransitionHydrationLane
    • TransitionLanes
    • RetryLanes
    • SelectiveHydrationLane
    • IdleHydrationLane
    • IdleLane
    • OffscreenLane
  • Dispatcher - memoizedState
    • useCallback - [callback, deps]
    • useDeferredValue - OnlyNonUrgentLanes
    • useContext
interface Fiber {
tag: WorkTag; // 工作类型
key;
type;
ref;
elementType; // element.type
stateNode;
pendingProps; // new,unresolved
memoizedProps; // old
updateQueue;
memoizedState; // hook
dependencies; // contexts, events
mode: TypeOfMode; // 运行类型
// Effect
flags: Flags;
subtreeFlags: Flags;
deletions: Array<Fiber> | null;

nextEffect: Fiber | null;
firstEffect: Fiber | null;
lastEffect: Fiber | null;

lanes: Lanes;
childLanes: Lanes;
// fiber 成对出现,这是另外一个 - 两个 tree 的 fiber
alternate: Fiber | null;

// 树 - 链表
return?: Fiber; // 上级节点
child?: Fiber; // 第一个子节点 - 多个子节点表现为 第一个的相邻节点
sibling?: Fiber; // 相邻节点
index: number;

// enableProfilerTimer
actualDuration?: number;
actualStartTime?: number;
selfBaseDuration?: number;
treeBaseDuration?: number;
}

interface Hook {
memoizedState: any;
baseState: any;
baseQueue: Update<any, any> | null;
queue: any;
// 更新时的 新的 Hook
next: Hook | null;
}

interface Effect {
// HasEffect,Insertion,Layout,Passive
tag: HookFlags;
create: () => (() => void) | void;
destroy: (() => void) | void;
deps: Array<mixed> | null;
next: Effect;
}

const createFiber = (tag: WorkTag, pendingProps: mixed, key: null | string, mode: TypeOfMode): Fiber => {
return new FiberNode(tag, pendingProps, key, mode);
};
const createWorkInProgress = (current: Fiber, pendingProps: any): Fiber => {
const wip = current.alternate ?? createFiber(current.tag, pendingProps, current.key, current.mode);
if (!current.alternate) {
wip.elementType = current.elementType;
wip.type = current.type;
wip.stateNode = current.stateNode;

wip.alternate = current;
current.alternate = wip;
}
// copy props from current to wip
return wip;
};
WorkTag
export const FunctionComponent = 0;
export const ClassComponent = 1;
export const IndeterminateComponent = 2; // Before we know whether it is function or class
export const HostRoot = 3; // Root of a host tree. Could be nested inside another node.
export const HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
export const HostComponent = 5;
export const HostText = 6;
export const Fragment = 7;
export const Mode = 8;
export const ContextConsumer = 9;
export const ContextProvider = 10;
export const ForwardRef = 11;
export const Profiler = 12;
export const SuspenseComponent = 13;
export const MemoComponent = 14;
export const SimpleMemoComponent = 15;
export const LazyComponent = 16;
export const IncompleteClassComponent = 17;
export const DehydratedFragment = 18;
export const SuspenseListComponent = 19;
export const ScopeComponent = 21;
export const OffscreenComponent = 22;
export const LegacyHiddenComponent = 23;
export const CacheComponent = 24;
export const TracingMarkerComponent = 25;
TypeOfMode
export const NoMode = /*                         */ 0b000000;
// TODO: Remove ConcurrentMode by reading from the root tag instead
export const ConcurrentMode = /* */ 0b000001;
export const ProfileMode = /* */ 0b000010;
export const DebugTracingMode = /* */ 0b000100;
export const StrictLegacyMode = /* */ 0b001000;
export const StrictEffectsMode = /* */ 0b010000;
export const ConcurrentUpdatesByDefaultMode = /* */ 0b100000;

Fast Refresh

/* @refresh reset */

HMR - Hot Module Replacement

// vite
// deps, cb
import.meta.hot.accept((newModule) => {
if (newModule) {
// newModule is undefined when SyntaxError happened
console.log('updated: count is now ', newModule.count);
}
});

// webpack
import.meta.webpackHot.accept(
dependencies, // Either a string or an array of strings
callback, // Function to fire when the dependencies are updated
errorHandler, // (err, {moduleId, dependencyId}) => {}
);
  • Vite HMR API
    • import.meta.hot
      • accept
      • dispose
      • data
      • decline
      • invalidate
      • on
      • send
  • Webpack HMR API
    • cjs module.hot
    • esm import.meta.webpackHot

react-is

  • 通过构造的 $$typeof 来判断是否为内部对象类型
  • .$$typeof
    • ELEMENT
      • .type
        • FRAGMENT
        • PROFILER
        • STRICT_MODE
        • SUSPENSE
        • SUSPENSE_LIST
    • PORTAL
    • SERVER_CONTEXT
    • CONTEXT
    • FORWARD_REF
    • LAZY
    • MEMO
    • PROVIDER
  • isAsyncMode
  • ReactIS
  • ReactSymbols

Offscreen

const Offscreen = React.unstable_Offscreen;
const Hello = () => {
return (
<Offscreen mode={hidden ? 'hidden' : 'visible'}>
<Component />
</Offscreen>
);
};

Experimental

Server Component

  • 不支持特性
    • React.Component
    • React.PureComponent
    • React.createContext
    • hooks
  • 约定
    • "use client", "use server" 标记组件类型
    • 会使用 react-server exports
  • RFC: Server Module Conventions