DEV Community

Cover image for React 19: New API use(promise)
Jaime
Jaime

Posted on

React 19: New API use(promise)

In this post, I’ll demo how to read a value from a promise using use.

Links

Snippet

Let’s check out the following code:

import { Suspense } from "react";

export default function Page() {
  const messagePromise = fetchMessages();

  return (
    <Suspense fallback={<p> waiting for messages...</p>}>
      <Message messagePromise={messagePromise} />
    </Suspense>
  );
}
Enter fullscreen mode Exit fullscreen mode

A couple of things to note:

  • <Suspense /> is being used, which basically displays the fallback, in this case: ⌛ waiting for messages..., until the promise is resolved.

  • messagePromise is a promise passed as a prop to <Message />.

Now, let’s take a look at fetchMessages:

async function fetchMessages() {
  return [
    {
      id: 1,
      text: "message 1",
    },
    {
      id: 2,
      text: "message 2",
    },
  ];
}
Enter fullscreen mode Exit fullscreen mode

As you can see, it’s a very simple function. In a real world example, this could be a fetch request, but for simplicity, the function just returns an array. By using async, JavaScript automatically knows that the function returns a promise.

Finally, let’s check out the <Message> component:

function Message({ messagePromise }) {
  const comments = use(messagePromise);

  return comments.map((comment) => <p key={comment.id}>{comment.text}</p>);
}
Enter fullscreen mode Exit fullscreen mode

This is where it gets interesting. The <Message> component receives messagePromise as a prop, which, as we mentioned, is a promise.

Usually, you’d use await with a promise, but in React 19, you can now use use to achieve basically the same result.

One key difference between await and use is that await blocks rendering until the promise is resolved, whereas use doesn’t block rendering.

Here’s how the component looks before the promise is resolved:

React 19 use: before promise is resolved

And once the promise is resolved:

React 19 use: after before promise is resolved

Conclusion

use works similarly to await, and if the application is running on a server using SSR, the result is exactly the same: the server will return the same HTML response in both cases.

However, if the code runs on the client, rendering behaves a bit differently. await blocks rendering until the promise is resolved, while use allows the component to re-render once the promise is resolved.

Top comments (3)

Collapse
 
deepansh_johri_cc5bd700a7 profile image
Deepansh Johri

What will be the output if we use await here , will there be any difference ??

Collapse
 
garciadiazjaime profile image
Jaime

Hi @deepansh_johri_cc5bd700a7 ,

Message is a React component, and typically you would have something like this:

async function Message({ messagePromise }) {
  const comments = await messagePromise;

  return comments.map((comment) => <p key={comment.id}>{comment.text}</p>);
}
Enter fullscreen mode Exit fullscreen mode

Notice: that messagePromise is already a returned promise value from a function.

So instead of using the async function modifier and await, React 19 now lets you resolve the promise with use

In terms of output, it might depend on where the code is executed: Server vs. Client. However, ultimately, the result will be the same

Additionally, @tim_goyer_b3415aeb32d74e5 is right about the case when "inside the body of useEffect"

Collapse
 
tim_goyer_b3415aeb32d74e5 profile image
Tim Goyer

You can't have an async hook.

This fixes the issue with writing an async function inside the body of useEffect and then immediately calling it.

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs