79819798

Date: 2025-11-14 08:43:00
Score: 0.5
Natty:
Report link

There is a pattern where you can trigger a Server Function call from within a Client Component, that returns another Client Component, wrapped in Suspense.

This pattern works seamlessly in Dinou, a React 19 framework, and with some current limitation in Waku, another React 19 framework.

I wrote a post about it.

But I will put here the code anyway (using Dinou). It's very simple.

First we define the Server Function.

"use server";

// import the Client Component
import UserProfile from "@/components/user-profile";

export async function userProfile() {
  // Fetch from DB or API
  const name = await new Promise((resolve) => setTimeout(() => resolve("John"), 3000));

  // Return Client Component with props filled with data
  return <UserProfile name={name} />;
}

Next we define the Client Component returned by the Server Function.

"use client";

export default function UserProfile({name}){
  return <div>{name}</div>
}

Finally, we define the page component, a Client Component, from where we trigger the call to the Server Function.

"use client";

import Suspense from "react-enhanced-suspense";
import { userProfile} from "@/server-functions/user-profile";

export default function Page() {
  return (
    <div>
      <Suspense fallback="Loading..." resourceId="user-profile">
        {() => userProfile()}
      </Suspense>
    </div>
  );
}

As you can see I use Suspense from react-enhanced-suspense in the example shown. This is because when used like this, the promise returned by the Server Function will remain stable between re-renders of the Client Component, and only be re-invoked, the Server Function, when resourceId changes.

Then we can do something like this:

"use client";

import Suspense from "react-enhanced-suspense";
import { aServerFunctionWithArgs} from "@/server-functions/a-server-function-with-args";
import { useState } from "react";

export default function Page() {
  const [arg1, setArg1] = useState("foo");

  return (
    <div>
      <Suspense fallback="Loading..." resourceId={`user-profile-${arg1}`}>
        {() => aServerFunctionWithArgs(arg1)}
      </Suspense>
    </div>
  );
}

In this last case the Server Function will be re-invoked dynamically whenever its arguments change.

Suspense from react-enhanced-suspense it's exactly React's Suspense when no extra prop is used.

Reasons:
  • Contains signature (1):
  • Long answer (-1):
  • Has code block (-0.5):
  • Low reputation (1):
Posted by: roggc