|
| 1 | +# React on Rails 15.0.0 Release Notes |
| 2 | + |
| 3 | +## Major Features |
| 4 | + |
| 5 | +### 🚀 React Server Components Support |
| 6 | +Experience the future of React with full RSC integration in your Rails apps: |
| 7 | +- Seamlessly use React Server Components |
| 8 | +- Reduce client bundle sizes |
| 9 | +- Enable powerful new patterns for data fetching |
| 10 | +- ⚡️ Requires React on Rails Pro - [See the full tutorial](https://www.shakacode.com/react-on-rails-pro/docs/react-server-components-tutorial) |
| 11 | + |
| 12 | +### Improved Component Hydration |
| 13 | +Major improvements to component and store hydration: |
| 14 | +- Components and stores now hydrate immediately rather than waiting for page load |
| 15 | +- Enables faster hydration, especially beneficial for streamed pages |
| 16 | +- Components can hydrate before the page is fully streamed |
| 17 | +- Can use `async` scripts in the page with no fear of race condition |
| 18 | +- No need to use `defer` anymore |
| 19 | + |
| 20 | +## Breaking Changes |
| 21 | + |
| 22 | +### Component Hydration Changes |
| 23 | +- The `defer_generated_component_packs` and `force_load` configurations now default to `false` and `true` respectively. This means components will hydrate early without waiting for the full page load. This improves performance by eliminating unnecessary delays in hydration. |
| 24 | + - The previous need for deferring scripts to prevent race conditions has been eliminated due to improved hydration handling. Making scripts not defer is critical to execute the hydration scripts early before the page is fully loaded. |
| 25 | + - The `force_load` configuration make `react-on-rails` hydrate components immediately as soon as their server-rendered HTML reaches the client, without waiting for the full page load. |
| 26 | + - If you want to keep the previous behavior, you can set `defer_generated_component_packs: true` or `force_load: false` in your `config/initializers/react_on_rails.rb` file. |
| 27 | + - If we want to keep the original behavior of `force_load` for only one or more components, you can set `force_load: false` in the `react_component` helper or `force_load` configuration. |
| 28 | + - Redux store support `force_load` option now and it uses `config.force_load` value as the default value. Which means that the redux store will hydrate immediately as soon as its server-side data reaches the client. You can override this behavior for individual redux stores by setting `force_load: false` in the `redux_store` helper. |
| 29 | + |
| 30 | +- `ReactOnRails.reactOnRailsPageLoaded()` is now an async function: |
| 31 | + - If you are manually calling this function to ensure components are hydrated (e.g. with async script loading), you must now await the promise it returns: |
| 32 | + ```js |
| 33 | + // Before |
| 34 | + ReactOnRails.reactOnRailsPageLoaded(); |
| 35 | + // Code expecting all components to be hydrated |
| 36 | + |
| 37 | + // After |
| 38 | + await ReactOnRails.reactOnRailsPageLoaded(); |
| 39 | + // Code expecting all components to be hydrated |
| 40 | + ``` |
| 41 | + |
| 42 | +## Store Dependencies for Components |
| 43 | + |
| 44 | +When using Redux stores with multiple components, you need to explicitly declare store dependencies to optimize hydration. Here's how: |
| 45 | + |
| 46 | +### The Problem |
| 47 | + |
| 48 | +If you have deferred Redux stores and components like this: |
| 49 | + |
| 50 | +```erb |
| 51 | +<% redux_store("SimpleStore", props: @app_props_server_render, defer: true) %> |
| 52 | +<%= react_component('ReduxApp', {}, {prerender: true}) %> |
| 53 | +<%= react_component('ComponentWithNoStore', {}, {prerender: true}) %> |
| 54 | +<%= redux_store_hydration_data %> |
| 55 | +``` |
| 56 | + |
| 57 | +By default, React on Rails assumes components depend on all previously created stores. This means: |
| 58 | +- Neither `ReduxApp` nor `ComponentWithNoStore` will hydrate until `SimpleStore` is hydrated |
| 59 | +- Since the store is deferred to the end of the page, both components are forced to wait unnecessarily |
| 60 | + |
| 61 | +### The Solution |
| 62 | + |
| 63 | +Explicitly declare store dependencies for each component: |
| 64 | + |
| 65 | +```erb |
| 66 | +<% redux_store("SimpleStore", props: @app_props_server_render, defer: true) %> |
| 67 | +<%= react_component('ReduxApp', {}, { |
| 68 | + prerender: true |
| 69 | + <!-- No need to specify store_dependencies - it automatically depends on SimpleStore --> |
| 70 | +}) %> |
| 71 | +<%= react_component('ComponentWithNoStore', {}, { |
| 72 | + prerender: true, |
| 73 | + store_dependencies: [] <!-- Explicitly declare no store dependencies --> |
| 74 | +}) %> |
| 75 | +<%= redux_store_hydration_data %> |
| 76 | +``` |
| 77 | + |
| 78 | +This allows `ComponentWithNoStore` to hydrate immediately without waiting for `SimpleStore`, improving page performance. |
| 79 | + |
| 80 | +## Pull Requests |
| 81 | +- [PR 1644](https://github.com/shakacode/react_on_rails/pull/1644) by [@AbanoubGhadban](https://github.com/AbanoubGhadban) - React Server Components Support |
| 82 | +- [PR 1656](https://github.com/shakacode/react_on_rails/pull/1656) by [@AbanoubGhadban](https://github.com/AbanoubGhadban) - Improved Component Hydration |
0 commit comments