Dhruv Property
Dhruv Property

Reputation: 11

React Suspense Without using Lazy

Till now i know React suspense uses promises to handle async rendering and fallback rendering which we can achieve using React.lazy for dynamic import. But i have read that we can also use suspense without lazy. But now how it work now? And try to explain with example with Async component which uses setTimeOut which resolve promise after 2sec. and render main content after 2sec fallback ui.

And try to explain with example with Async component which uses setTimeOut which resolve promise after 2sec. and render main content after 2sec fallback ui.

Upvotes: 0

Views: 355

Answers (1)

christopher
christopher

Reputation: 1

Starting with React 19, the new "use" API is one way to make use of Suspense. The official docs demonstrate how "use" and Suspense work together: https://react.dev/reference/react/use#streaming-data-from-server-to-client

Here's an example from a demo application:

function TimesheetLoader({ customerId }: { customerId: string }) {
  const customerPromise = fetch(`${BASE_API_URL}/customers/${customerId}`).then(
    (r) => r.json() as Promise<Customer>
  );
  const timeEntriesPromise = fetch(
    `${BASE_API_URL}/customers/${customerId}/timeEntries`
  ).then((r) => r.json() as Promise<TimeEntry[]>);
  return (
    <ErrorBoundary
      fallback={
        <div>Error: something went wrong while loading timesheet page</div>
      }
    >
      <Suspense fallback={<div>loading customer and time entries...</div>}>
        <TimesheetInner
          customerId={customerId}
          timeEntriesPromise={timeEntriesPromise}
          customerPromise={customerPromise}
        />
      </Suspense>
    </ErrorBoundary>
  );
}

Here we have a simple React component that makes two HTTP requests using the "fetch" API. It assigns the promises to a couple variables, and passes those in as props to a "TimesheetInner" component. That child component, then, can use the "use" function to effectively await that promise before proceeding with rendering:

function TimesheetInner({
  timeEntriesPromise,
  customerPromise,
}: {
  customerId: string;
  timeEntriesPromise: Promise<TimeEntry[]>;
  customerPromise: Promise<Customer>;
}) {
  const customer = use(customerPromise);
  const customerName = customer.name;
  const timeEntries = use(timeEntriesPromise);

  return (
    <>
      {/* ... render timesheet here ... */}
    </>
  )
}

if you use the TanStack Query library (react-query) for managing HTTP requests, they also have a suspense option - the docs for using react-query with Suspense can be found here: https://tanstack.com/query/v4/docs/framework/react/guides/suspense

Neither of these use cases involve React.lazy. I don't have an example with a setTimeout, but if you can set up your timeout in such a way that it's in a function that returns a promise, you can then use that with the "use" function and wrap the component in a Suspense. That doesn't seem like a great use case for Suspense though.

Upvotes: 0

Related Questions