Building with React Server Components and Client Components in RedwoodSDK
At RedwoodSDK, we're embracing the latest patterns recommended by the React team by combining React Server Components (RSC) with client components to build efficient and scalable interfaces.
Here's a quick example of our setup:
✅ React Server Component
// src/app/Home.tsx
import { Suspense } from "react";
import UsersList from "./UsersList";
import { getUsers } from "./functions";
export default function Home() {
const usersPromise = getUsers();
return (
<div>
<h1>Home</h1>
<Suspense fallback={<p>Loading users...</p>}>
<UsersList usersPromise={usersPromise} />
</Suspense>
</div>
);
}
This is a React Server Component that fetches data on the server using the server function getUsers()
, then passes the promise to a client component.
✅ Server Action (getUsers
)
// src/app/functions.ts
"use server";
import { db } from "@/db";
export async function getUsers() {
const users = await db.user.findMany();
return users;
}
This function runs on the server and fetches data from our D1 Prisma-powered database.
✅ Client Component
// src/app/UsersList.tsx
"use client";
import { use } from "react";
import { User } from "@prisma/client";
export default function UsersList({ usersPromise }: { usersPromise: Promise<User[]> }) {
// NOTE: this will resume the promise from the server.
// It will suspend until the data is available.
const users = use(usersPromise);
return (
<div>
{users.map((user: User) => (
<div key={user.id}>
<h1>{user.username}</h1>
</div>
))}
</div>
);
}
Why This Approach is Better
This pattern provides several advantages:
Zero Client-Side Fetching
The data is fetched entirely on the server. NouseEffect
, no loading spinners, no API calls from the client.Streaming and Suspense-Friendly
By returning a promise to the client component, React can pause rendering until the data is ready. This works well with React'sSuspense
and streaming.Less Boilerplate
Compared to usinguseEffect
and state management to fetch and store users, this method eliminates complexity and makes components easier to test and maintain.Faster Time-to-Content
Data fetching happens during server render, resulting in faster Time To First Byte (TTFB) and less JavaScript sent to the browser.
Final Thoughts
By combining React Server Components with use()
in client components, RedwoodSDK developers can leverage React’s modern data-fetching patterns to build fast, clean, and efficient UIs with minimal client-side logic.
This method aligns with React’s long-term vision: server-first rendering with selective interactivity where needed.