mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
db281b3d9c
This adds a new capability for renderers (React DOM, React Native): prevent a tree from being displayed until it is ready, showing a fallback if necessary, but without blocking the React components from being evaluated in the meantime. A concrete example is CSS loading: React DOM can block a commit from being applied until the stylesheet has loaded. This allows us to load the CSS asynchronously, while also preventing a flash of unstyled content. Images and fonts are some of the other use cases. You can think of this as "Suspense for the commit phase". Traditional Suspense, i.e. with `use`, blocking during the render phase: React cannot proceed with rendering until the data is available. But in the case of things like stylesheets, you don't need the CSS in order to evaluate the component. It just needs to be loaded before the tree is committed. Because React buffers its side effects and mutations, it can do work in parallel while the stylesheets load in the background. Like regular Suspense, a "suspensey" stylesheet or image will trigger the nearest Suspense fallback if it hasn't loaded yet. For now, though, we only do this for non-urgent updates, like with startTransition. If you render a suspensey resource during an urgent update, it will revert to today's behavior. (We may or may not add a way to suspend the commit during an urgent update in the future.) In this PR, I have implemented this capability in the reconciler via new methods added to the host config. I've used our internal React "no-op" renderer to write tests that demonstrate the feature. I have not yet implemented Suspensey CSS, images, etc in React DOM. @gnoff and I will work on that in subsequent PRs.
62 lines
1.4 KiB
JavaScript
62 lines
1.4 KiB
JavaScript
/**
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
* @flow
|
|
*/
|
|
|
|
/**
|
|
* This is a renderer of React that doesn't have a render target output.
|
|
* It is useful to demonstrate the internals of the reconciler in isolation
|
|
* and for testing semantics of reconciliation separate from the host
|
|
* environment.
|
|
*/
|
|
|
|
import ReactFiberReconciler from 'react-reconciler';
|
|
import createReactNoop from './createReactNoop';
|
|
|
|
export const {
|
|
_Scheduler,
|
|
getChildren,
|
|
dangerouslyGetChildren,
|
|
getPendingChildren,
|
|
dangerouslyGetPendingChildren,
|
|
getOrCreateRootContainer,
|
|
createRoot,
|
|
createLegacyRoot,
|
|
getChildrenAsJSX,
|
|
getPendingChildrenAsJSX,
|
|
getSuspenseyThingStatus,
|
|
resolveSuspenseyThing,
|
|
resetSuspenseyThingCache,
|
|
createPortal,
|
|
render,
|
|
renderLegacySyncRoot,
|
|
renderToRootWithID,
|
|
unmountRootWithID,
|
|
findInstance,
|
|
flushNextYield,
|
|
startTrackingHostCounters,
|
|
stopTrackingHostCounters,
|
|
expire,
|
|
flushExpired,
|
|
batchedUpdates,
|
|
deferredUpdates,
|
|
discreteUpdates,
|
|
idleUpdates,
|
|
flushDiscreteUpdates,
|
|
flushSync,
|
|
flushPassiveEffects,
|
|
act,
|
|
dumpTree,
|
|
getRoot,
|
|
// TODO: Remove this once callers migrate to alternatives.
|
|
// This should only be used by React internals.
|
|
unstable_runWithPriority,
|
|
} = createReactNoop(
|
|
ReactFiberReconciler, // reconciler
|
|
false, // useMutation
|
|
);
|