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
Copy file name to clipboardExpand all lines: docs/oss/api-reference/generator-details.md
+29-25Lines changed: 29 additions & 25 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
# Generator Details
2
2
3
-
The `react_on_rails:install` generator combined with the example pull requests of generator runs will get you up and running efficiently. There's a fair bit of setup with integrating a bundler with Rails. Most options default to off — for example, the default for `-R` is that `redux` is off. The exception is the bundler: **fresh installs now default to Rspack**, so pass `--no-rspack` (or its alias `--webpack`) if you want Webpack instead. Existing apps that already declare a bundler in `config/shakapacker.yml` are left unchanged.
3
+
The `react_on_rails:install` generator combined with the example pull requests of generator runs will get you up and running efficiently. There's a fair bit of setup with integrating a bundler with Rails. Most options default to off. The exception is the bundler: **fresh installs now default to Rspack**, so pass `--no-rspack` (or its alias `--webpack`) if you want Webpack instead. Existing apps that already declare a bundler in `config/shakapacker.yml` are left unchanged.
4
4
5
5
Run `rails generate react_on_rails:install --help` for descriptions of all available options:
6
6
@@ -9,7 +9,6 @@ Usage:
9
9
rails generate react_on_rails:install [options]
10
10
11
11
Options:
12
-
-R, [--redux], [--no-redux] # Install Redux package and Redux version of Hello World Example. Default: false
[--rspack], [--no-rspack] # Use Rspack (default) as the bundler; pass --no-rspack to use Webpack
15
14
[--webpack], [--no-webpack] # Use Webpack as the bundler (alias for --no-rspack)
@@ -27,13 +26,17 @@ Runtime options:
27
26
Description:
28
27
29
28
The react_on_rails:install generator integrates webpack with rails with ease. You
30
-
can pass the redux option if you'd like to have redux setup for you automatically.
31
-
32
-
* Redux
33
-
34
-
Passing the --redux generator option causes the generated Hello World example
35
-
to integrate the Redux state container framework. The necessary node modules
36
-
will be automatically included for you.
29
+
can pass the options below to customize the generated example and supporting
30
+
configuration.
31
+
32
+
> [!WARNING]
33
+
> The Redux installer path (`--redux` / `-R`) is a hidden legacy escape hatch, not
34
+
> a recommended starter architecture. New apps should start with plain
35
+
> `react_component` entries, React local state or context for island-local UI
36
+
> state, and Rails props or server-state tools such as TanStack Query for data
37
+
> loaded from the server. Use Redux only for an existing Redux app or an advanced
38
+
> multi-island page where separate React roots must coordinate through one shared
39
+
> client store.
37
40
38
41
* TypeScript
39
42
@@ -82,9 +85,9 @@ Another good option is to create a simple test app per the [Tutorial](../getting
82
85
83
86
## Understanding the Organization of the Generated Client Code
84
87
85
-
The React on Rails generator creates different directory structures depending on whether you use the `--redux` option.
88
+
The React on Rails generator normally creates the simple component structure below. A hidden legacy Redux path remains available for existing apps and recovery work, but it is not the structure recommended for new React on Rails apps.
86
89
87
-
### Default Structure (Without Redux)
90
+
### Default Structure (Recommended, Without Redux)
88
91
89
92
The basic generator creates a simple, flat structure optimized for auto-bundling:
90
93
@@ -104,9 +107,9 @@ app/javascript/
104
107
105
108
For components that need different client vs. server implementations, use `.client.jsx` and `.server.jsx` suffixes (e.g., `HelloWorld.client.jsx` and `HelloWorld.server.jsx`).
106
109
107
-
### Redux Structure (With`--redux`Option)
110
+
### Legacy Redux Structure (Hidden`--redux`Path)
108
111
109
-
The Redux generator creates a more structured organization with familiar Redux patterns:
112
+
The hidden legacy Redux generator creates a more structured organization with familiar Redux patterns:
110
113
111
114
```text
112
115
app/javascript/
@@ -130,13 +133,21 @@ app/javascript/
130
133
└── helloWorldStore.js
131
134
```
132
135
133
-
This structure follows Redux best practices:
136
+
This legacy structure is useful only when you intentionally maintain Redux:
134
137
135
138
-**`components/`**: Presentational "dumb" components that receive data via props
136
139
-**`containers/`**: Container "smart" components connected to Redux store
137
140
-**`actions/`** and **`reducers/`**: Standard Redux patterns
138
141
-**`ror_components/`**: Entry point files that initialize Redux and render the app
139
142
143
+
If you already have a React on Rails app and intentionally need to recreate the legacy Redux example, use the direct hidden generator after the base installer has configured React on Rails:
For full install recovery of an older Redux-generated app, the hidden `react_on_rails:install --redux` option still exists, but do not use it for greenfield apps.
150
+
140
151
### TypeScript Support
141
152
142
153
The generator also supports a `--typescript` option for generating TypeScript files:
@@ -206,11 +217,8 @@ For apps with custom webpack configurations, review the generated config templat
Do not combine RSC with the hidden legacy Redux installer for new apps. Existing Redux Client Components can continue to work beside RSC when Redux access stays in Client Components; see [RSC context and state migration](../migrating/rsc-context-and-state.md#redux-toolkit).
313
+
310
314
**Upgrading an existing Pro app to RSC:**
311
315
312
316
For existing Pro apps, use the standalone RSC generator:
Copy file name to clipboardExpand all lines: docs/oss/api-reference/redux-store-api.md
+13-7Lines changed: 13 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,25 +1,31 @@
1
-
# Redux Store
1
+
# Redux Store API
2
2
3
3
> [!WARNING]
4
4
>
5
-
> 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."
5
+
> This runtime API remains supported for existing apps and advanced shared-store use cases, but it is not recommended as the default state model for new React on Rails apps. Prefer the standard `react_component` view helper with props or a render-function unless multiple React islands must coordinate through one client store.
6
6
7
7
> [!IMPORTANT]
8
8
>
9
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
10
11
-
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.
11
+
You don't need to use the `redux_store`API to use Redux inside a single React root. This API was set up to support multiple calls to `react_component` on one page that all talk to the same Redux store.
12
12
13
-
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."
13
+
If you are rendering one React component on a page, pass props to that component through `react_component` and keep local UI state inside that React tree. A render-function is also a better fit when you need `railsContext`, routing setup, or custom hydration behavior for one root.
14
14
15
-
Consider using the `redux_store` helper for the two following use cases:
15
+
Choose state ownership before reaching for `redux_store`:
16
+
17
+
-**Local island state:** use React Hooks or React Context inside one `react_component` root.
18
+
-**Server state:** use Rails controller props for initial data, then Rails JSON endpoints, GraphQL, or a server-state cache such as [TanStack Query](../building-features/tanstack-query.md) for data that belongs on the server.
19
+
-**Multi-island shared client state:** use `redux_store` when separate React roots on one Rails page must read and update the same client-side state.
20
+
21
+
Consider using the `redux_store` helper for the following advanced use cases:
16
22
17
23
1. You want to have multiple React components accessing the same store at once.
18
24
2. You want to place the props to hydrate the client side stores at the very end of your HTML, probably server rendered, so that the browser can render all earlier HTML first. This is particularly useful if your props will be large. However, you're probably better off using [React on Rails Pro](../../pro/react-on-rails-pro.md) if you're at all concerned about performance.
19
25
20
-
## Multiple React Components on a Page with One Store
26
+
## Multiple React Islands on a Page with One Store
21
27
22
-
You may wish to have 2 React components share the same the Redux store. For example, if your navbar is a React component, you may want it to use the same store as your component in the main area of the page. You may even want multiple React components in the main area, which allows for greater modularity. Also, you may want this to work with Turbolinks to minimize reloading the JavaScript.
28
+
You may wish to have two separate React roots share the same Redux store. For example, if your navbar is a React component, you may want it to use the same store as your component in the main area of the page. You may even want multiple React components in the main area, which allows for greater modularity. Also, you may want this to work with Turbo or Turbolinks to minimize reloading the JavaScript.
23
29
24
30
A good example of this would be something like a notifications counter in a header. As each notification is read in the body of the page, you would like to update the header. If both the header and body share the same Redux store, then this is trivial. Otherwise, we have to rely on other solutions, such as the header polling the server to see how many unread notifications exist.
Copy file name to clipboardExpand all lines: docs/oss/building-features/react-and-redux.md
+4-2Lines changed: 4 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,12 +1,14 @@
1
-
# Communication between React Components and Redux Reducers
1
+
# Legacy Redux Reducer Guidance
2
+
3
+
Redux remains supported for existing React on Rails apps and advanced pages that need one client store shared across multiple React roots. For new apps, prefer local component state for island-specific UI, Rails props plus server-state tools for server-owned data, and reach for Redux only when those smaller patterns do not fit.
2
4
3
5
## Communication Between Components
4
6
5
7
See [Sharing State Between Components](https://react.dev/learn/sharing-state-between-components).
6
8
7
9
## Redux Reducers
8
10
9
-
The `helloWorld/reducers/index.jsx` example that results from running the generator with the Redux option may be slightly confusing because of its simplicity. For clarity, what follows is a more fleshed-out example of what a reducer might look like:
11
+
The `helloWorld/reducers/index.jsx` example from the hidden legacy Redux generator may be slightly confusing because of its simplicity. For clarity, what follows is a more fleshed-out example of what a reducer might look like:
Copy file name to clipboardExpand all lines: docs/oss/building-features/react-router.md
+28-3Lines changed: 28 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -37,9 +37,34 @@ React Router v6 offers multiple routing approaches. For React on Rails, we recom
37
37
38
38
**Note on Data Mode:** React Router's Data Mode (with loaders/actions) is designed for SPAs where the client handles data fetching. Since React on Rails uses Rails controllers to load data and pass it as props to React components, Data Mode would create duplicate data loading. Stick with Declarative Mode to leverage React on Rails' server-side data loading pattern.
39
39
40
-
## Basic Client-Side Setup with Redux
40
+
## Basic Client-Side Setup
41
41
42
-
If you're using Redux (created with `rails generate react_on_rails:install --redux`), you can add React Router by wrapping your app:
42
+
Most React Router integrations do not need Redux. Route ordinary components inside one React root, pass initial data from Rails as props, and use your normal server-state approach for follow-up data loading.
constHome= ({ name }) =><div>Hello, {name}!</div>;
51
+
constAbout= () =><div>About</div>;
52
+
53
+
constRouterApp= (props) => (
54
+
<BrowserRouter>
55
+
<Routes>
56
+
<Route path="/" element={<Home {...props} />} />
57
+
<Route path="/about" element={<About />} />
58
+
</Routes>
59
+
</BrowserRouter>
60
+
);
61
+
62
+
exportdefaultRouterApp;
63
+
```
64
+
65
+
## Legacy Client-Side Setup with Redux
66
+
67
+
If you're maintaining an app that already uses Redux, including the hidden legacy Redux generator output, you can add React Router by wrapping your app:
Copy file name to clipboardExpand all lines: docs/oss/core-concepts/auto-bundling-file-system-based-automated-bundle-generation.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
@@ -728,7 +728,7 @@ As of version 13.3.4, bundles inside directories that match `config.components_s
728
728
## Redux Store Auto-Registration
729
729
730
730
> [!NOTE]
731
-
> Most applications use React components without Redux. If you don't use Redux stores, you can skip this section entirely.
731
+
> Most applications use React components without Redux. If you don't maintain a legacy Redux app or an advanced multi-island shared store, you can skip this section entirely.
732
732
733
733
In addition to components, React on Rails can automatically register Redux stores based on file system conventions. This eliminates manual `ReactOnRails.registerStore()` calls and generates individual packs for each store. The feature works the same way as component auto-registration.
Copy file name to clipboardExpand all lines: docs/oss/core-concepts/how-react-on-rails-works.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
@@ -8,7 +8,7 @@ Ensure these generated bundle files are in your `.gitignore`, as you never want
8
8
9
9
Inside your Rails views, you can now use the `react_component` helper method provided by React on Rails. You can pass props directly to the React component helper.
10
10
11
-
Optionally, you can also initialize a Redux store with the view or controller helper `redux_store` so that the Redux store can be shared amongst multiple React components.
11
+
For legacy or advanced shared-store pages, you can also initialize a Redux store with the view or controller helper `redux_store` so that separate React roots can coordinate through one client store.
12
12
13
13
## Client-Side Rendering vs. Server-Side Rendering
> You never make these calls. React on Rails makes these calls when it does either client or server rendering. You will define functions that take these 2 params and return a React component or a Redux Store. Naturally, you do not have to use second parameter, `railsContext`, if you do not need it. If you don't take a second parameter, then you're probably defining a React function component and you will simply return a React Element, often just JSX.
79
79
80
80
> [!NOTE]
81
-
> See [Redux Store](../api-reference/redux-store-api.md#multiple-react-components-on-a-page-with-one-store) on how to set up Redux stores that allow multiple components to talk to the same store.
81
+
> See [Redux Store](../api-reference/redux-store-api.md#multiple-react-islands-on-a-page-with-one-store) on how to set up Redux stores that allow multiple React roots to talk to the same store.
82
82
83
83
The `railsContext` has: (see the implementation in [ReactOnRails::Helper](https://github.com/shakacode/react_on_rails/blob/main/react_on_rails/lib/react_on_rails/helper.rb), method `rails_context` for the definitive list).
0 commit comments