React Structure
React 源代码基础结构理解:
- React Core: all top-level APIs;React core only includes the APIs necessary to define components
- React Render: ReactDOMRender / ReactNativeRender / RaxRender / WeexRender …
- React Reconcilers: share a lot of logic among different renders, especially the declarative rendering algorithms, reconciliation algorithm.
- Stack Reconciler (React 15 based)
- Fiber Reconciler (React 16 based)
:::info 分层架构,IoC 的实践;经济体的 LowcodeEngine 也借鉴了不少类似的分层模式; :::
Hooks

export function useEffect(create: () => (() => void) | void,deps: Array<mixed> | void | null,): void {const dispatcher = resolveDispatcher();return dispatcher.useEffect(create, deps);}
- Fiber Tree
- Fiber:renderWithHooks 函数的实现背景
- Dispatcher & Resolver
ReactFiberHooks.new.js- ReactCurrentDispatcher.current 👈 为了兼容渲染层 RenderDriver 而实现的 .current 指向 ReactDOM or ReactNative or Remax Driver
- Mount Hook on Fiber
function mountWorkInProgressHook(): Hook {const hook: Hook = {memoizedState: null,baseState: null,baseQueue: null,queue: null,next: null,};if (workInProgressHook === null) {// This is the first hook in the listcurrentlyRenderingFiber.memoizedState = workInProgressHook = hook;} else {// Append to the end of the listworkInProgressHook = workInProgressHook.next = hook;}return workInProgressHook;}
- useState() :
- 初始化:数据、调用队列和 Reducer
- 更新:dispatchAction => Fiber 节点上的 queue 对象,链式处理 state
- useEffect():
- 初始化:Fiber 节点的 updateQueue,并使用 .next 属性做关联实现调用链
一些小技巧
- React 源代码组织: pacakges/
share公共类型、API、方法的目录; __DEV__区分编译时和运行时;ReactFuatureFlags &
|=Operator 的奇妙用法;用 bitwise 运算去巧妙解决 flags 的问题;currentlyRenderingFiber.effectTag |= fiberEffectTag;
invariant()function andconsole.errorfunction;Runtime v.s. Compile Time; ```javascript /**- Use invariant() to assert state which your program assumes to be true. *
- Provide sprintf-style format (only %s is supported) and arguments
- to provide information about what broke and what you were
- expecting. *
- The invariant message will be stripped in production, but the invariant
- will remain to ensure logic does not differ in production. */
export default function invariant(condition, format, a, b, c, d, e, f) { throw new Error( ‘Internal React error: invariant() is meant to be replaced at compile ‘ + ‘time. There is no runtime version.’, ); }
- 经典的: `__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED` 猜测一下为啥要透露这些变量呢?```javascriptReact.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIREDconst ReactSharedInternals = {ReactCurrentDispatcher,ReactCurrentBatchConfig,ReactCurrentOwner,IsSomeRendererActing,// Used by renderers to avoid bundling object-assign twice in UMD bundles:assign,};
感受
- React 级别的项目,洁癖也没有「那么好」😄
- Comment / DevInfo 至关重要
- flow 🗑
- comment system 各种自我怀疑
使用 Hooks 注意
- 防止在条件、循环、return 语句中使用 Hooks
- 没有 re-render 的需求的渲染函数,尽量少用 useState,相反,使用 useRef 减少重新渲染次数
- useEffect 的依赖和销毁回调函数需要引起重视
- 涉及多次 setState 的 Hook 函数调用的时候,优先选择函数而非具体值
参考
- 官方指南:Codebase Overview
- ReactHooks 源码分析
