You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fix fictional API names, missing associations, form_with, and CSRF patterns in RSC docs
Replace stream_react_component_with_async_props (fictional, 18 occurrences)
with the real stream_react_component helper. Replace getReactOnRailsAsyncProp
(fictional, 38 occurrences) with direct prop access. Remove WithAsyncProps
type references. Rewrite ERB examples to pass all data as regular props
instead of using the nonexistent block/emit pattern.
Fix as_json calls that access nested associations (specs, reviews) by adding
include: option. Add local: true to form_with example for Rails < 6.1
compatibility. Replace CSRF token prop pattern with
ReactOnRails.authenticityToken() in three form examples.
Fixes#2802
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: docs/oss/migrating/migrating-to-rsc.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -112,7 +112,7 @@ Tailored for React on Rails' multi-root architecture:
112
112
113
113
1.**[Prepare your app](rsc-preparing-app.md)** -- set up the RSC infrastructure, add `'use client'` to all component entry points, and switch to streaming rendering. The app works identically -- nothing changes yet.
114
114
2.**Pick a component and push the boundary down** -- move `'use client'` from the root component to its interactive children, letting parent components become Server Components.
115
-
3.**Adopt advanced patterns** -- add Suspense boundaries, [async props](rsc-data-fetching.md#data-fetching-in-react-on-rails-pro) for streaming data from Rails, and server-side data fetching.
115
+
3.**Adopt advanced patterns** -- add Suspense boundaries, [`stream_react_component`](rsc-data-fetching.md#data-fetching-in-react-on-rails-pro) for streaming SSR, and server-side data fetching.
116
116
4.**Repeat for each registered component** -- migrate components one at a time, in any order.
117
117
118
118
This approach lets you migrate incrementally, one component at a time, without ever breaking your app.
@@ -329,49 +329,34 @@ export default function Homepage() {
329
329
330
330
**Key insight:** `Homepage` (a Server Component) is the component that imports and renders `Header`, `MainContent`, and `Footer`. Since `Homepage` owns these children, they remain Server Components -- even though they're visually nested inside the Client Component `ColorProvider`.
In React on Rails, use async props to stream dataprogressively. Eachasync prop streams to the browser independently as it becomes ready, and Suspense boundaries show fallbacks until the data arrives:
334
+
In React on Rails, `stream_react_component` uses React's streaming SSR (`renderToPipeableStream`) to deliver HTML progressively. Rails passes all data as props, and the streaming infrastructure delivers the rendered output efficiently:
335
335
336
336
```erb
337
-
<%# ERB view — sync props render the shell, async props stream in %>
Each `<Suspense>` boundary enables independent streaming --the user sees content progressively as each async prop resolves, rather than waiting for the slowest query.
369
+
`stream_react_component` streams the rendered HTML progressively to the browser. All data is available as props -- no client-side fetching or loading states needed.
385
370
386
-
## Pattern 5:Async Props to Client Components via `use()`
371
+
## Pattern 5: Server Data to Interactive Client Components
387
372
388
-
Pass an async prop promise to a Client Component that resolves it with the `use()`hook. This lets data stream from Rails whilethe Client Component handles interactivity:
373
+
Pass server-fetched data from Rails to a Client Component that adds interactivity. The Server Component receives the data as props and passes it to the Client Component:
389
374
390
375
```erb
391
-
<%# ERB view — sync props render the shell, comments stream in %>
**Benefits:** The post title and body render immediately as sync props. Comments stream in when Rails calls `emit.call("comments", ...)`. The Client Component resolves the promise with`use()` and can add interactivity (e.g., reply buttons).
439
-
440
-
>**Warning:** Never create promises inside Client Components for`use()`--this causes the "uncached promise" runtime error. See [Common `use()` Mistakes](rsc-data-fetching.md#common-use-mistakes-in-client-components) for why and what to do instead.
422
+
**Benefits:** The Server Component handles data display with zero JavaScript cost. The Client Component receives pre-fetched data as props and adds only the interactivity it needs (reply buttons, expand/collapse).
## Pattern 3: Streaming Slow Data with Async Props
124
124
125
-
> **Note:** This section covers a cross-cutting concern (data fetching via async props) that affects how you structure context and state. For the full treatment of data fetching patterns, see [Data Fetching Migration](rsc-data-fetching.md).
125
+
> **Note:** This section covers a cross-cutting concern (data fetching via `stream_react_component`) that affects how you structure context and state. For the full treatment of data fetching patterns, see [Data Fetching Migration](rsc-data-fetching.md).
126
126
127
-
In React on Rails, data comes from Rails as props. Some data is available immediately (user session, page title), but other data requires expensive queries (analytics, recommendations, external APIs). With **async props**, you send the fast data as regular props so the shell renders immediately, and stream the slow data in the background as it becomes ready.
127
+
In React on Rails, data comes from Rails as props. Rails fetches all data in the controller and passes it to `stream_react_component`, which uses React's streaming SSR to deliver the rendered HTML progressively.
The component renders its shell (`name`, `price`) instantly. Each async prop streams in when Rails finishes computing it, filling in Suspense boundaries progressively:
136
+
The component renders with all data available as props. `stream_react_component` uses React's streaming SSR to deliver the HTML progressively:
@@ -173,11 +160,11 @@ async function Reviews({ reviewsPromise }) {
173
160
}
174
161
```
175
162
176
-
`getReactOnRailsAsyncProp(key)` returns a cached Promise (same object on repeated calls), so you can pass it to multiple children -- Server Components `await` it, Client Components resolve it with `use()`. No `React.cache()` or Context wiring needed.
163
+
All props are available immediately in the component. `stream_react_component` handles progressive HTML delivery via React's `renderToPipeableStream`.
177
164
178
165
> **Note:**`React.cache()` is only available in React Server Component environments. It is not available in client components or non-RSC server rendering (e.g., `renderToString`).
179
166
180
-
> For the full async props API, TypeScript typing, and more examples, see [Data Fetching in React on Rails Pro](rsc-data-fetching.md#data-fetching-in-react-on-rails-pro).
167
+
> For more streaming patterns and examples, see [Data Fetching in React on Rails Pro](rsc-data-fetching.md#data-fetching-in-react-on-rails-pro).
181
168
182
169
## Migrating Global State Libraries
183
170
@@ -281,13 +268,13 @@ Zustand and Jotai follow the same pattern as Redux: keep all store access in Cli
281
268
282
269
RSC reduces the need for global state libraries because data fetching moves to the server:
0 commit comments