Skip to content

上下文 Context

执行栈环境

注意: 这个执行栈环境 不是函数的上下文,也不是 createContext这个上下文。

这是React中将整个执行过程区分为不同的上下文环境,具体可以分为

js


export const NoContext = /*             */ 0b0000000;
// 批量更新的 渲染执行栈环境 著名的 unstable_batchedUpdates 、setState
const BatchedContext = /*               */ 0b0000001;
// 事件
const EventContext = /*                 */ 0b0000010;
const DiscreteEventContext = /*         */ 0b0000100;
// Legacy模式下 render的同步渲染执行栈环境
const LegacyUnbatchedContext = /*       */ 0b0001000;
// Render执行栈环境 beginWork、completeWork()阶段执行的上下文
const RenderContext = /*                */ 0b0010000;
// 渲染执行栈环境 commit()阶段执行的上下文
const CommitContext = /*                */ 0b0100000;

CommitContext

commit阶段的执行栈环境(这个环境是不可以被任务队列打断的)

RenderContext

render 阶段的执行栈环境,这边涉及到一个问题:

为什么React的任务是异步可中断。具体可以看 React异步可中断

LegacyUnbatchedContext

legacy模式下 在初始化渲染的时候 会不执行批量更新,从而尽快渲染并不能被打断。这就是ReactDOM.render()是同步的原因。

js
function legacyRenderSubtreeIntoContainer(
  parentComponent: ?React$Component<any, any>,
  children: ReactNodeList,
  container: Container,
  forceHydrate: boolean,
  callback: ?Function,
) {
  if (!root) {
    // Initial mount should not be batched.
    // 初始渲染 不执行批量更新,需要尽快渲染并不能被打断
    unbatchedUpdates(() => {
      updateContainer(children, fiberRoot, parentComponent, callback);
    });
  } else {
    // Update
    updateContainer(children, fiberRoot, parentComponent, callback);
  }
  return getPublicRootInstance(fiberRoot);
}

在初次渲染的时候 updateContainer的函数是执行在 unbatchedUpdates中的

js
/**
 * 设置为 任务同步执行的执行栈环境
 * @param {*} fn
 * @param {*} a
 * @returns
 */
export function unbatchedUpdates<A, R>(fn: (a: A) => R, a: A): R {
  // 缓存之前的执行栈环境
  const prevExecutionContext = executionContext;
  executionContext &= ~BatchedContext;
  // 通过 按位与 设置为 任务同步执行的执行栈环境
  executionContext |= LegacyUnbatchedContext;
  try {
    return fn(a);
  } finally {
    executionContext = prevExecutionContext;
    if (executionContext === NoContext) {
      // Flush the immediate callbacks that were scheduled during this batch
      resetRenderTimer();
      flushSyncCallbackQueue();
    }
  }
}

BatchedContext

批量更新的执行栈环境

对于这个环境,我们看的最多的就是 setState方法 和 React.unstable_batchedUpdates()