rwsdk
Version:
Build fast, server-driven webapps on Cloudflare with SSR, RSC, and realtime
2 lines (1 loc) • 3.36 kB
TypeScript
export declare const react = "\n# React, React Server Components, and React Server Functions Rules\n\n## React Server Components (RSC)\n\n1. By default, all components are server components unless explicitly marked as client components.\n2. Server components are rendered on the server as HTML and streamed to the browser.\n3. Server components cannot include client-side interactivity (state, effects, event handlers).\n4. Server components can directly fetch data and include it in the initial payload.\n5. Server components can be async and can be wrapped in Suspense boundaries.\n\nExample:\n\n```tsx\nexport default function MyServerComponent() {\n return <div>Hello, from the server!</div>;\n}\n```\n\n## Client Components\n\n1. Must be explicitly marked with the \"use client\" directive at the top of the file.\n2. Required when the component needs:\n - Interactivity (click handlers, state management)\n - Browser APIs\n - Event listeners\n - Client-side effects\n - Client-side routing\n3. Will be hydrated by React in the browser.\n\nExample:\n\n```tsx\n\"use client\";\n\nexport default function MyClientComponent() {\n return <button onClick={() => console.log(\"clicked\")}>Click me</button>;\n}\n```\n\n## Data Fetching in Server Components\n\n1. Server components can directly fetch data without useEffect or other client-side data fetching methods.\n2. Use Suspense boundaries to handle loading states for async server components.\n3. Pass context (ctx) through props to child components that need it.\n\nExample:\n\n```tsx\nexport async function TodoList({ ctx }) {\n const todos = await db.todo.findMany({ where: { userId: ctx.user.id } });\n\n return (\n <ol>\n {todos.map((todo) => (\n <li key={todo.id}>{todo.title}</li>\n ))}\n </ol>\n );\n}\n```\n\n## Server Functions\n\n1. Must be marked with the \"use server\" directive at the top of the file.\n2. Can be imported and used in client components.\n3. Execute on the server when called from client components.\n4. Have access to the request context via requestInfo.ctx.\n5. Can handle form submissions and other server-side operations.\n\nExample:\n\n```tsx\n\"use server\";\n\nimport { requestInfo } from \"rwsdk/worker\";\n\nexport async function addTodo(formData: FormData) {\n const { ctx } = requestInfo;\n const title = formData.get(\"title\");\n await db.todo.create({ data: { title, userId: ctx.user.id } });\n}\n```\n\n## Context Usage\n\n1. Context is available to all server components and server functions.\n2. Access context via:\n - requestInfo in server functions:\n ```\n import { requestInfo } from \"rwsdk/worker\";\n const { ctx } = requestInfo\n ```\n3. Context is populated by middleware and interruptors and is request-scoped.\n\n## Best Practices\n\n1. Keep server components as the default choice unless client-side interactivity is needed.\n2. Use client components only when necessary to minimize the JavaScript bundle size.\n3. Leverage server components for data fetching and initial rendering.\n4. Use Suspense boundaries appropriately for loading states.\n5. Keep client components as small as possible, moving server-side logic to server components or server functions.\n6. Always mark client components with \"use client\" directive.\n7. Always mark server functions with \"use server\" directive.\n\n";