@samitouri / QOS-React-2 / commits / 5eb78d0a04

Pass ThenableState to replaySuspendedUnitOfWork

Tiny refactor to refine the work loop variable so Flow knows it's not null when we access it in replaySuspendedUnitOfWork.

Andrew Clark committed Nov 2, 2022 at 14:18 UTC 5eb78d0a04dee8fa14189a31c19831dd390225cb
2 files changed +80 -52
packages/react-reconciler/src/ReactFiberWorkLoop.new.js
+40 -26
@@ -2202,24 +2202,29 @@ function renderRootConcurrent(root: FiberRoot, lanes: Lanes) {
2202 break;
2203 }
2204 case SuspendedOnData: {
2205 - const didResolve =
2206 - workInProgressSuspendedThenableState !== null &&
2207 - isThenableStateResolved(workInProgressSuspendedThenableState);
2208 - if (didResolve) {
2209 - workInProgressSuspendedReason = NotSuspended;
2210 - workInProgressThrownValue = null;
2211 - replaySuspendedUnitOfWork(unitOfWork, thrownValue);
2212 - } else {
2213 - // The work loop is suspended on data. We should wait for it to
2214 - // resolve before continuing to render.
2215 - const thenable: Thenable<mixed> = (workInProgressThrownValue: any);
2216 - const onResolution = () => {
2217 - ensureRootIsScheduled(root, now());
2218 - };
2219 - thenable.then(onResolution, onResolution);
2220 - break outer;
2205 + if (workInProgressSuspendedThenableState !== null) {
2206 + const thenableState = workInProgressSuspendedThenableState;
2207 + if (isThenableStateResolved(thenableState)) {
2208 + // The data resolved. Try rendering the component again.
2209 + workInProgressSuspendedReason = NotSuspended;
2210 + workInProgressThrownValue = null;
2211 + replaySuspendedUnitOfWork(
2212 + unitOfWork,
2213 + thrownValue,
2214 + thenableState,
2215 + );
2216 + break;
2217 + }
2218 }
2222 - break;
2219 +
2220 + // The work loop is suspended on data. We should wait for it to
2221 + // resolve before continuing to render.
2222 + const thenable: Thenable<mixed> = (workInProgressThrownValue: any);
2223 + const onResolution = () => {
2224 + ensureRootIsScheduled(root, now());
2225 + };
2226 + thenable.then(onResolution, onResolution);
2227 + break outer;
2228 }
2229 case SuspendedOnImmediate: {
2230 // If this fiber just suspended, it's possible the data is already
@@ -2237,17 +2242,25 @@ function renderRootConcurrent(root: FiberRoot, lanes: Lanes) {
2242 break outer;
2243 }
2244 default: {
2245 + if (workInProgressSuspendedThenableState !== null) {
2246 + const thenableState = workInProgressSuspendedThenableState;
2247 + if (isThenableStateResolved(thenableState)) {
2248 + // The data resolved. Try rendering the component again.
2249 + workInProgressSuspendedReason = NotSuspended;
2250 + workInProgressThrownValue = null;
2251 + replaySuspendedUnitOfWork(
2252 + unitOfWork,
2253 + thrownValue,
2254 + thenableState,
2255 + );
2256 + break;
2257 + }
2258 + }
2259 +
2260 + // Otherwise, unwind then continue with the normal work loop.
2261 workInProgressSuspendedReason = NotSuspended;
2262 workInProgressThrownValue = null;
2242 - const didResolve =
2243 - workInProgressSuspendedThenableState !== null &&
2244 - isThenableStateResolved(workInProgressSuspendedThenableState);
2245 - if (didResolve) {
2246 - replaySuspendedUnitOfWork(unitOfWork, thrownValue);
2247 - } else {
2248 - unwindSuspendedUnitOfWork(unitOfWork, thrownValue);
2249 - }
2250 - // Continue with the normal work loop.
2263 + unwindSuspendedUnitOfWork(unitOfWork, thrownValue);
2264 break;
2265 }
2266 }
@@ -2335,6 +2348,7 @@ function performUnitOfWork(unitOfWork: Fiber): void {
2348 function replaySuspendedUnitOfWork(
2349 unitOfWork: Fiber,
2350 thrownValue: mixed,
2351 + thenableState: ThenableState,
2352 ): void {
2353 // This is a fork of performUnitOfWork specifcally for replaying a fiber that
2354 // just suspended.
packages/react-reconciler/src/ReactFiberWorkLoop.old.js
+40 -26
@@ -2202,24 +2202,29 @@ function renderRootConcurrent(root: FiberRoot, lanes: Lanes) {
2202 break;
2203 }
2204 case SuspendedOnData: {
2205 - const didResolve =
2206 - workInProgressSuspendedThenableState !== null &&
2207 - isThenableStateResolved(workInProgressSuspendedThenableState);
2208 - if (didResolve) {
2209 - workInProgressSuspendedReason = NotSuspended;
2210 - workInProgressThrownValue = null;
2211 - replaySuspendedUnitOfWork(unitOfWork, thrownValue);
2212 - } else {
2213 - // The work loop is suspended on data. We should wait for it to
2214 - // resolve before continuing to render.
2215 - const thenable: Thenable<mixed> = (workInProgressThrownValue: any);
2216 - const onResolution = () => {
2217 - ensureRootIsScheduled(root, now());
2218 - };
2219 - thenable.then(onResolution, onResolution);
2220 - break outer;
2205 + if (workInProgressSuspendedThenableState !== null) {
2206 + const thenableState = workInProgressSuspendedThenableState;
2207 + if (isThenableStateResolved(thenableState)) {
2208 + // The data resolved. Try rendering the component again.
2209 + workInProgressSuspendedReason = NotSuspended;
2210 + workInProgressThrownValue = null;
2211 + replaySuspendedUnitOfWork(
2212 + unitOfWork,
2213 + thrownValue,
2214 + thenableState,
2215 + );
2216 + break;
2217 + }
2218 }
2222 - break;
2219 +
2220 + // The work loop is suspended on data. We should wait for it to
2221 + // resolve before continuing to render.
2222 + const thenable: Thenable<mixed> = (workInProgressThrownValue: any);
2223 + const onResolution = () => {
2224 + ensureRootIsScheduled(root, now());
2225 + };
2226 + thenable.then(onResolution, onResolution);
2227 + break outer;
2228 }
2229 case SuspendedOnImmediate: {
2230 // If this fiber just suspended, it's possible the data is already
@@ -2237,17 +2242,25 @@ function renderRootConcurrent(root: FiberRoot, lanes: Lanes) {
2242 break outer;
2243 }
2244 default: {
2245 + if (workInProgressSuspendedThenableState !== null) {
2246 + const thenableState = workInProgressSuspendedThenableState;
2247 + if (isThenableStateResolved(thenableState)) {
2248 + // The data resolved. Try rendering the component again.
2249 + workInProgressSuspendedReason = NotSuspended;
2250 + workInProgressThrownValue = null;
2251 + replaySuspendedUnitOfWork(
2252 + unitOfWork,
2253 + thrownValue,
2254 + thenableState,
2255 + );
2256 + break;
2257 + }
2258 + }
2259 +
2260 + // Otherwise, unwind then continue with the normal work loop.
2261 workInProgressSuspendedReason = NotSuspended;
2262 workInProgressThrownValue = null;
2242 - const didResolve =
2243 - workInProgressSuspendedThenableState !== null &&
2244 - isThenableStateResolved(workInProgressSuspendedThenableState);
2245 - if (didResolve) {
2246 - replaySuspendedUnitOfWork(unitOfWork, thrownValue);
2247 - } else {
2248 - unwindSuspendedUnitOfWork(unitOfWork, thrownValue);
2249 - }
2250 - // Continue with the normal work loop.
2263 + unwindSuspendedUnitOfWork(unitOfWork, thrownValue);
2264 break;
2265 }
2266 }
@@ -2335,6 +2348,7 @@ function performUnitOfWork(unitOfWork: Fiber): void {
2348 function replaySuspendedUnitOfWork(
2349 unitOfWork: Fiber,
2350 thrownValue: mixed,
2351 + thenableState: ThenableState,
2352 ): void {
2353 // This is a fork of performUnitOfWork specifcally for replaying a fiber that
2354 // just suspended.