行数
https://github.com/a8397550/react-source-share/blob/master/default/react-dom-default.js

代码行数 21526行 scheduleUpdateOnFiber

执行 21911 行 renderRoot(root, Sync, true); // 返回了一个这个哦 commitRoot.bind(…)
注意 21654 行 scheduleCallbackForRoot

  1. var scheduleWork = scheduleUpdateOnFiber;
  2. function scheduleUpdateOnFiber(fiber, expirationTime) {
  3. checkForNestedUpdates();
  4. warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber);
  5. var root = markUpdateTimeFromFiberToRoot(fiber, expirationTime);
  6. if (root === null) {
  7. warnAboutUpdateOnUnmountedFiberInDEV(fiber);
  8. return;
  9. }
  10. // NoWork 常量 0
  11. root.pingTime = NoWork;
  12. function checkForInterruption(fiberThatReceivedUpdate, updateExpirationTime) {
  13. // 初始化时 变量 workInProgressRoot = null
  14. // 常量 enableUserTimingAPI = true
  15. if (enableUserTimingAPI && workInProgressRoot !== null &&
  16. // updateExpirationTime = 1073741823
  17. // 变量 renderExpirationTime = 0
  18. updateExpirationTime > renderExpirationTime) {
  19. interruptedBy = fiberThatReceivedUpdate;
  20. }
  21. }
  22. checkForInterruption(fiber, expirationTime);
  23. // record 记录 [ˈrekɔːd , rɪˈkɔːd]
  24. // schedule 工作计划 [ˈskedʒuːl]
  25. function recordScheduleUpdate() {
  26. // enableUserTimingAPI 常量 true
  27. if (enableUserTimingAPI) {
  28. // 变量 初始化时 = false
  29. if (isCommitting) {
  30. hasScheduledUpdateInCurrentCommit = true;
  31. }
  32. // 初始化时 currentPhase = null
  33. if (currentPhase !== null &&
  34. currentPhase !== 'componentWillMount'
  35. && currentPhase !== 'componentWillReceiveProps') {
  36. hasScheduledUpdateInCurrentPhase = true;
  37. }
  38. }
  39. }
  40. recordScheduleUpdate();
  41. // React-DOM render 源码分析二 介绍过这个方法
  42. // 初始化时 priorityLevel = 97
  43. var priorityLevel = getCurrentPriorityLevel();
  44. // 初始化时 expirationTime === 1073741823 === 1073741823 === Sync
  45. // true
  46. if (expirationTime === Sync) {
  47. if (
  48. // 常量 NoContext = 0
  49. // 初始化时 executionContext = 8 LegacyUnbatchedContext = 8
  50. // 8 & 8 = 8 下条语句初始化时结果为true
  51. (executionContext & LegacyUnbatchedContext) !== NoContext &&
  52. // 初始化 (8 & (16 | 32)) === NoContext 结果为true
  53. (executionContext & (RenderContext | CommitContext)) === NoContext) {
  54. // 初始化时,此方法啥也没干
  55. schedulePendingInteractions(root, expirationTime);
  56. var callback = renderRoot(root, Sync, true);
  57. while (callback !== null) {
  58. callback = callback(true);
  59. }
  60. } else {
  61. scheduleCallbackForRoot(root, ImmediatePriority, Sync);
  62. if (executionContext === NoContext) {
  63. flushSyncCallbackQueue();
  64. }
  65. }
  66. } else {
  67. scheduleCallbackForRoot(root, priorityLevel, expirationTime);
  68. }
  69. if ((executionContext & DiscreteEventContext) !== NoContext && (
  70. // Only updates at user-blocking priority or greater are considered
  71. // discrete, even inside a discrete event.
  72. priorityLevel === UserBlockingPriority$2 || priorityLevel === ImmediatePriority)) {
  73. // This is the result of a discrete event. Track the lowest priority
  74. // discrete update per root so we can flush them early, if needed.
  75. if (rootsWithPendingDiscreteUpdates === null) {
  76. rootsWithPendingDiscreteUpdates = new Map([[root, expirationTime]]);
  77. } else {
  78. var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(root);
  79. if (lastDiscreteTime === undefined || lastDiscreteTime > expirationTime) {
  80. rootsWithPendingDiscreteUpdates.set(root, expirationTime);
  81. }
  82. }
  83. }
  84. }
  85. function checkForNestedUpdates() {
  86. // nestedUpdateCount = 0 , 常量 NESTED_UPDATE_LIMIT = 50
  87. if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
  88. nestedUpdateCount = 0;
  89. rootWithNestedUpdates = null;
  90. (function () {
  91. {
  92. {
  93. throw ReactError(Error('Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.'));
  94. }
  95. }
  96. })();
  97. }
  98. {
  99. // nestedPassiveUpdateCount = 0, 常量 NESTED_PASSIVE_UPDATE_LIMIT = 50
  100. if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {
  101. nestedPassiveUpdateCount = 0;
  102. warning$1(false, 'Maximum update depth exceeded. This can happen when a component ' + "calls setState inside useEffect, but useEffect either doesn't " + 'have a dependency array, or one of the dependencies changes on ' + 'every Render.');
  103. }
  104. }
  105. }
  106. function warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber) {
  107. {
  108. // 初始化时,fiber.tag = 3, ClassComponent 常量 1
  109. if (fiber.tag === ClassComponent) {
  110. switch (phase) {
  111. case 'getChildContext':
  112. if (didWarnAboutUpdateInGetChildContext) {
  113. return;
  114. }
  115. warningWithoutStack$1(false, 'setState(...): Cannot call setState() inside getChildContext()');
  116. didWarnAboutUpdateInGetChildContext = true;
  117. break;
  118. case 'render':
  119. if (didWarnAboutUpdateInRender) {
  120. return;
  121. }
  122. warningWithoutStack$1(false, 'Cannot update during an existing state transition (such as ' + 'within `Render`). Render methods should be a pure function of ' + 'props and state.');
  123. didWarnAboutUpdateInRender = true;
  124. break;
  125. }
  126. }
  127. }
  128. }
  1. function markUpdateTimeFromFiberToRoot(fiber, expirationTime) {
  2. // 初始化时
  3. // expirationTime = 1073741823
  4. // fiber.expirationTime = 0
  5. if (fiber.expirationTime < expirationTime) {
  6. fiber.expirationTime = expirationTime;
  7. }
  8. // 初始化 fiber.alternate = null
  9. var alternate = fiber.alternate;
  10. if (alternate !== null && alternate.expirationTime < expirationTime) {
  11. alternate.expirationTime = expirationTime;
  12. }
  13. // 初始化时 fiber.return = null
  14. var node = fiber.return;
  15. var root = null;
  16. // 常量 3
  17. if (node === null && fiber.tag === HostRoot) {
  18. // fiber.stateNode = FiberRootNode
  19. root = fiber.stateNode;
  20. } else {
  21. while (node !== null) {
  22. alternate = node.alternate;
  23. if (node.childExpirationTime < expirationTime) {
  24. node.childExpirationTime = expirationTime;
  25. if (alternate !== null && alternate.childExpirationTime < expirationTime) {
  26. alternate.childExpirationTime = expirationTime;
  27. }
  28. } else if (alternate !== null && alternate.childExpirationTime < expirationTime) {
  29. alternate.childExpirationTime = expirationTime;
  30. }
  31. if (node.return === null && node.tag === HostRoot) {
  32. root = node.stateNode;
  33. break;
  34. }
  35. node = node.return;
  36. }
  37. }
  38. if (root !== null) {
  39. // 初始化时 root.firstPendingTime = 0;
  40. // 英first 首个 [fɜːst]
  41. var firstPendingTime = root.firstPendingTime;
  42. if (expirationTime > firstPendingTime) {
  43. root.firstPendingTime = expirationTime;
  44. }
  45. // 初始化 root.lastPendingTime = 0;
  46. var lastPendingTime = root.lastPendingTime;
  47. // NoWork = 0
  48. if (lastPendingTime === NoWork || expirationTime < lastPendingTime) {
  49. root.lastPendingTime = expirationTime;
  50. }
  51. }
  52. return root;
  53. }
  1. function schedulePendingInteractions(root, expirationTime) {
  2. // root FiberRootNode
  3. // expirationTime === 1073741823
  4. // 常量 enableSchedulerTracing = true
  5. if (!enableSchedulerTracing) {
  6. return;
  7. }
  8. // var ReactInternals$2 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
  9. // var _ReactInternals$Sched$1 = ReactInternals$2.SchedulerTracing;
  10. // var __interactionsRef = _ReactInternals$Sched$1.__interactionsRef;
  11. // 加载react-dom时初始化 ,render前就有值了 __interactionsRef.current: Set(0) {}
  12. scheduleInteractions(root, expirationTime, __interactionsRef.current);
  13. }
  14. function scheduleInteractions(root, expirationTime, interactions) {
  15. // 常量 true
  16. if (!enableSchedulerTracing) {
  17. return;
  18. }
  19. if (interactions.size > 0) {
  20. var pendingInteractionMap = root.pendingInteractionMap;
  21. var pendingInteractions = pendingInteractionMap.get(expirationTime);
  22. if (pendingInteractions != null) {
  23. interactions.forEach(function (interaction) {
  24. if (!pendingInteractions.has(interaction)) {
  25. // Update the pending async work count for previously unscheduled interaction.
  26. interaction.__count++;
  27. }
  28. pendingInteractions.add(interaction);
  29. });
  30. } else {
  31. pendingInteractionMap.set(expirationTime, new Set(interactions));
  32. // Update the pending async work count for the current interactions.
  33. interactions.forEach(function (interaction) {
  34. interaction.__count++;
  35. });
  36. }
  37. var subscriber = __subscriberRef.current;
  38. if (subscriber !== null) {
  39. var threadID = computeThreadID(root, expirationTime);
  40. subscriber.onWorkScheduled(interactions, threadID);
  41. }
  42. }
  43. }