Skip to content

Commit 8c50236

Browse files
justin808claude
andcommitted
Document Redux shared store caveat with async: true
Added comprehensive documentation explaining why Redux shared stores with inline component registration require defer: true instead of async: true. Changes: - docs/streaming: Added "Important: Redux Shared Store Caveat" section - docs/redux-store-api: Added IMPORTANT callout about script loading - Explains the root cause: async scripts execute before inline scripts - Provides 3 solutions: use defer, move registration to bundle, or use Pro Root cause analysis: With async: true, the bundle executes as soon as it downloads, which can be before inline <script> tags in the HTML that register components. This causes "Could not find component registered with name" errors. With defer: true, scripts wait for HTML parsing to complete, ensuring inline registration scripts run before the bundle attempts hydration. React on Rails Pro's getOrWaitForStore can handle async loading by waiting for registration to complete. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent ca8c985 commit 8c50236

File tree

2 files changed

+23
-0
lines changed

2 files changed

+23
-0
lines changed

docs/api-reference/redux-store-api.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
>
55
> This Redux API is no longer recommended as it prevents dynamic code splitting for performance. Instead, you should use the standard `react_component` view helper passing in a "Render-Function."
66
7+
> [!IMPORTANT]
8+
>
9+
> **Script Loading Requirement:** If you use Redux shared stores with inline component registration (registering components in view templates with `<script>ReactOnRails.register({ MyComponent })</script>`), you **must use `defer: true`** in your `javascript_pack_tag` instead of `async: true`. With async loading, the bundle may execute before inline scripts, causing component registration failures. See the [Streaming Server Rendering documentation](../building-features/streaming-server-rendering.md#important-redux-shared-store-caveat) for details and alternatives.
10+
711
You don't need to use the `redux_store` api to use Redux. This API was set up to support multiple calls to `react_component` on one page that all talk to the same Redux store.
812

913
If you are only rendering one React component on a page, as is typical to do a "Single Page App" in React, then you should _probably_ pass the props to your React component in a "Render-Function."

docs/building-features/streaming-server-rendering.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,25 @@ With Shakapacker ≥ 8.2.0, `async: true` is recommended even for non-streaming
257257

258258
Note: `async: true` with the `immediate_hydration` feature allows components to hydrate during page load, improving TTI even without streaming. See the Immediate Hydration section below for configuration details.
259259

260+
**⚠️ Important: Redux Shared Store Caveat**
261+
262+
If you are using Redux shared stores with the `redux_store` helper and **inline script registration** (registering components in view templates with `<script>ReactOnRails.register({ MyComponent })</script>`), you must use `defer: true` instead of `async: true`:
263+
264+
```erb
265+
<!-- ⚠️ REQUIRED for Redux shared stores with inline registration -->
266+
<%= javascript_pack_tag('client-bundle', 'data-turbo-track': 'reload', defer: true) %>
267+
```
268+
269+
**Why?** With `async: true`, the bundle executes immediately upon download, potentially **before** inline `<script>` tags in the HTML execute. This causes component registration failures when React on Rails tries to hydrate the component.
270+
271+
**Solutions:**
272+
273+
1. **Use `defer: true`** - Ensures proper execution order (inline scripts run before bundle)
274+
2. **Move registration to bundle** - Register components in your JavaScript bundle instead of inline scripts (recommended)
275+
3. **Use React on Rails Pro** - Pro's `getOrWaitForStore` and `getOrWaitForStoreGenerator` can handle async loading with inline registration
276+
277+
See the [Redux Store API documentation](../api-reference/redux-store-api.md) for more details on Redux shared stores.
278+
260279
#### Why Async is Better Than No Defer
261280

262281
With Shakapacker ≥ 8.2.0, using `async: true` provides the best performance:

0 commit comments

Comments
 (0)