MCPcopy Create free account
hub / github.com/microsoft/SandDance / updateSuspenseComponent

Function updateSuspenseComponent

docs/external/js/react-dom.development.js:17750–18007  ·  view source on GitHub ↗
(current, workInProgress, renderExpirationTime)

Source from the content-addressed store, hash-verified

17748 }
17749
17750 function updateSuspenseComponent(current, workInProgress, renderExpirationTime) {
17751 var mode = workInProgress.mode;
17752 var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend.
17753
17754 {
17755 if (shouldSuspend(workInProgress)) {
17756 workInProgress.effectTag |= DidCapture;
17757 }
17758 }
17759
17760 var suspenseContext = suspenseStackCursor.current;
17761 var nextDidTimeout = false;
17762 var didSuspend = (workInProgress.effectTag & DidCapture) !== NoEffect;
17763
17764 if (didSuspend || shouldRemainOnFallback(suspenseContext, current)) {
17765 // Something in this boundary's subtree already suspended. Switch to
17766 // rendering the fallback children.
17767 nextDidTimeout = true;
17768 workInProgress.effectTag &= ~DidCapture;
17769 } else {
17770 // Attempting the main content
17771 if (current === null || current.memoizedState !== null) {
17772 // This is a new mount or this boundary is already showing a fallback state.
17773 // Mark this subtree context as having at least one invisible parent that could
17774 // handle the fallback state.
17775 // Boundaries without fallbacks or should be avoided are not considered since
17776 // they cannot handle preferred fallback states.
17777 if (nextProps.fallback !== undefined && nextProps.unstable_avoidThisFallback !== true) {
17778 suspenseContext = addSubtreeSuspenseContext(suspenseContext, InvisibleParentSuspenseContext);
17779 }
17780 }
17781 }
17782
17783 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
17784 pushSuspenseContext(workInProgress, suspenseContext); // This next part is a bit confusing. If the children timeout, we switch to
17785 // showing the fallback children in place of the "primary" children.
17786 // However, we don't want to delete the primary children because then their
17787 // state will be lost (both the React state and the host state, e.g.
17788 // uncontrolled form inputs). Instead we keep them mounted and hide them.
17789 // Both the fallback children AND the primary children are rendered at the
17790 // same time. Once the primary children are un-suspended, we can delete
17791 // the fallback children — don't need to preserve their state.
17792 //
17793 // The two sets of children are siblings in the host environment, but
17794 // semantically, for purposes of reconciliation, they are two separate sets.
17795 // So we store them using two fragment fibers.
17796 //
17797 // However, we want to avoid allocating extra fibers for every placeholder.
17798 // They're only necessary when the children time out, because that's the
17799 // only time when both sets are mounted.
17800 //
17801 // So, the extra fragment fibers are only used if the children time out.
17802 // Otherwise, we render the primary children directly. This requires some
17803 // custom reconciliation logic to preserve the state of the primary
17804 // children. It's essentially a very basic form of re-parenting.
17805
17806 if (current === null) {
17807 // If we're currently hydrating, try to hydrate this boundary.

Callers 1

beginWorkFunction · 0.85

Calls 9

shouldSuspendFunction · 0.85
shouldRemainOnFallbackFunction · 0.85
pushSuspenseContextFunction · 0.85
createFiberFromFragmentFunction · 0.85
createWorkInProgressFunction · 0.85
reconcileChildFibersFunction · 0.85

Tested by

no test coverage detected