Module: ReactOnRailsProHelper
- Includes:
- ScoutApm::Tracer
- Defined in:
- app/helpers/react_on_rails_pro_helper.rb
Overview
rubocop:disable Metrics/ModuleLength
Instance Method Summary collapse
-
#async_react_component(component_name, options = {}) ⇒ ReactOnRailsPro::AsyncValue
Renders a React component asynchronously, returning an AsyncValue immediately.
-
#cached_async_react_component(component_name, raw_options = {}) { ... } ⇒ ReactOnRailsPro::AsyncValue, ReactOnRailsPro::ImmediateAsyncValue
Renders a React component asynchronously with caching support.
-
#cached_react_component(component_name, raw_options = {}, &block) ⇒ Object
Provide caching support for react_component in a manner akin to Rails fragment caching.
-
#cached_react_component_hash(component_name, raw_options = {}, &block) ⇒ Object
Provide caching support for react_component_hash in a manner akin to Rails fragment caching.
-
#cached_stream_react_component(component_name, raw_options = {}, &block) ⇒ Object
Provide caching support for stream_react_component in a manner akin to Rails fragment caching.
- #fetch_react_component(component_name, options) ⇒ Object
-
#rsc_payload_react_component(component_name, options = {}) ⇒ String
Renders the React Server Component (RSC) payload for a given component.
-
#stream_react_component(component_name, options = {}) ⇒ Object
Streams a server-side rendered React component using React’s ‘renderToPipeableStream`.
Instance Method Details
#async_react_component(component_name, options = {}) ⇒ ReactOnRailsPro::AsyncValue
Renders a React component asynchronously, returning an AsyncValue immediately. Multiple async_react_component calls will execute their HTTP rendering requests concurrently instead of sequentially.
Requires the controller to include ReactOnRailsPro::AsyncRendering and call enable_async_react_rendering.
241 242 243 244 245 246 247 248 249 250 251 252 253 |
# File 'app/helpers/react_on_rails_pro_helper.rb', line 241 def async_react_component(component_name, = {}) unless defined?(@react_on_rails_async_barrier) && @react_on_rails_async_barrier raise ReactOnRailsPro::Error, "async_react_component requires AsyncRendering concern. " \ "Include ReactOnRailsPro::AsyncRendering in your controller and call enable_async_react_rendering." end task = @react_on_rails_async_barrier.async do react_component(component_name, ) end ReactOnRailsPro::AsyncValue.new(task: task) end |
#cached_async_react_component(component_name, raw_options = {}) { ... } ⇒ ReactOnRailsPro::AsyncValue, ReactOnRailsPro::ImmediateAsyncValue
Renders a React component asynchronously with caching support. Cache lookup is synchronous - cache hits return immediately without async. Cache misses trigger async render and cache the result on completion.
All the same options as cached_react_component apply:
-
You must pass the props as a block (evaluated only on cache miss)
-
Provide the cache_key option
-
Optionally provide :cache_options for Rails.cache (expires_in, etc.)
-
Provide :if or :unless for conditional caching
274 275 276 277 278 279 |
# File 'app/helpers/react_on_rails_pro_helper.rb', line 274 def cached_async_react_component(component_name, = {}, &block) ReactOnRailsPro::Utils.with_trace(component_name) do (, block) fetch_async_react_component(component_name, , &block) end end |
#cached_react_component(component_name, raw_options = {}, &block) ⇒ Object
Provide caching support for react_component in a manner akin to Rails fragment caching. All the same options as react_component apply with the following difference:
-
You must pass the props as a block. This is so that the evaluation of the props is not done if the cache can be used.
-
Provide the cache_key option cache_key: String or Array (or Proc returning a String or Array) containing your cache keys. If prerender is set to true, the server bundle digest will be included in the cache key. The cache_key value is the same as used for conventional Rails fragment caching.
-
Optionally provide the ‘:cache_options` key with a value of a hash including as :compress, :expires_in, :race_condition_ttl as documented in the Rails Guides
-
Provide boolean values for ‘:if` or `:unless` to conditionally use caching.
52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'app/helpers/react_on_rails_pro_helper.rb', line 52 def cached_react_component(component_name, = {}, &block) ReactOnRailsPro::Utils.with_trace(component_name) do (, block) fetch_react_component(component_name, ) do = [:props] = yield [:skip_prerender_cache] = true [:auto_load_bundle] = ReactOnRails.configuration.auto_load_bundle || [:auto_load_bundle] react_component(component_name, ) end end end |
#cached_react_component_hash(component_name, raw_options = {}, &block) ⇒ Object
Provide caching support for react_component_hash in a manner akin to Rails fragment caching. All the same options as react_component_hash apply with the following difference:
-
You must pass the props as a block. This is so that the evaluation of the props is not done if the cache can be used.
-
Provide the cache_key option cache_key: String or Array (or Proc returning a String or Array) containing your cache keys. Since prerender is automatically set to true, the server bundle digest will be included in the cache key. The cache_key value is the same as used for conventional Rails fragment caching.
-
Optionally provide the ‘:cache_options` key with a value of a hash including as :compress, :expires_in, :race_condition_ttl as documented in the Rails Guides
-
Provide boolean values for ‘:if` or `:unless` to conditionally use caching.
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'app/helpers/react_on_rails_pro_helper.rb', line 79 def cached_react_component_hash(component_name, = {}, &block) [:prerender] = true ReactOnRailsPro::Utils.with_trace(component_name) do (, block) fetch_react_component(component_name, ) do = [:props] = yield [:skip_prerender_cache] = true [:auto_load_bundle] = ReactOnRails.configuration.auto_load_bundle || [:auto_load_bundle] react_component_hash(component_name, ) end end end |
#cached_stream_react_component(component_name, raw_options = {}, &block) ⇒ Object
Provide caching support for stream_react_component in a manner akin to Rails fragment caching. All the same options as stream_react_component apply with the following differences:
-
You must pass the props as a block. This is so that the evaluation of the props is not done if the cache can be used.
-
Provide the cache_key option cache_key: String or Array (or Proc returning a String or Array) containing your cache keys. Since prerender is automatically set to true, the server bundle digest will be included in the cache key. The cache_key value is the same as used for conventional Rails fragment caching.
-
Optionally provide the ‘:cache_options` key with a value of a hash including as :compress, :expires_in, :race_condition_ttl as documented in the Rails Guides
-
Provide boolean values for ‘:if` or `:unless` to conditionally use caching.
217 218 219 220 221 222 |
# File 'app/helpers/react_on_rails_pro_helper.rb', line 217 def cached_stream_react_component(component_name, = {}, &block) ReactOnRailsPro::Utils.with_trace(component_name) do (, block) fetch_stream_react_component(component_name, , &block) end end |
#fetch_react_component(component_name, options) ⇒ Object
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'app/helpers/react_on_rails_pro_helper.rb', line 12 def fetch_react_component(component_name, ) if ReactOnRailsPro::Cache.use_cache?() cache_key = ReactOnRailsPro::Cache.react_component_cache_key(component_name, ) Rails.logger.debug { "React on Rails Pro cache_key is #{cache_key.inspect}" } = [:cache_options] cache_hit = true result = Rails.cache.fetch(cache_key, ) do cache_hit = false yield end if cache_hit = ReactOnRails::ReactComponent::RenderOptions.new( react_component_name: component_name, options: ) load_pack_for_generated_component(component_name, ) end # Pass back the cache key in the results only if the result is a Hash if result.is_a?(Hash) result[:RORP_CACHE_KEY] = cache_key result[:RORP_CACHE_HIT] = cache_hit end result else yield end end |
#rsc_payload_react_component(component_name, options = {}) ⇒ String
This helper requires React Server Components support to be enabled in your configuration: ReactOnRailsPro.configure do |config|
config.enable_rsc_support = true
end
You don’t have to deal directly with this helper function - it’s used internally by the
Renders the React Server Component (RSC) payload for a given component. This helper generates a special format designed by React for serializing server components and transmitting them to the client.
Example NDJSON stream:
{"html":"<RSC Payload>","consoleReplayScript":"","hasErrors":false,"isShellReady":true}
{"html":"<RSC Payload>","consoleReplayScript":"console.log('Loading...')","hasErrors":false,"isShellReady":true}
The RSC payload within the html field contains:
-
The component’s rendered output from the server
-
References to client components that need hydration
-
Data props passed to client components
‘rsc_payload_route` helper function. The returned data from this function is used internally by components registered using the `registerServerComponent` function. Don’t use it unless you need more control over the RSC payload generation. To know more about RSC payload, see the following link:
192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'app/helpers/react_on_rails_pro_helper.rb', line 192 def rsc_payload_react_component(component_name, = {}) # rsc_payload_react_component doesn't have the prerender option # Because setting prerender to false will not do anything [:prerender] = true # Extract streaming-specific callback on_complete = .delete(:on_complete) consumer_stream_async(on_complete: on_complete) do internal_rsc_payload_react_component(component_name, ) end end |
#stream_react_component(component_name, options = {}) ⇒ Object
Streams a server-side rendered React component using React’s ‘renderToPipeableStream`. Supports React 18 features like Suspense, concurrent rendering, and selective hydration. Enables progressive rendering and improved performance for large components.
Note: This function can only be used with React on Rails Pro. The view that uses this function must be rendered using the ‘stream_view_containing_react_components` method from the React on Rails Pro gem.
Example of an async React component that can benefit from streaming:
const AsyncComponent = async () =>
const data = await fetchData();
return <div>{data</div>;
};
function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<AsyncComponent />
</Suspense>
);
}
Any other options are passed to the content tag, including the id.
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'app/helpers/react_on_rails_pro_helper.rb', line 127 def stream_react_component(component_name, = {}) # stream_react_component doesn't have the prerender option # Because setting prerender to false is equivalent to calling react_component with prerender: false [:prerender] = true if .key?(:immediate_hydration) ReactOnRails::Helper.warn_removed_immediate_hydration_option("stream_react_component") .delete(:immediate_hydration) end # Extract streaming-specific callback on_complete = .delete(:on_complete) consumer_stream_async(on_complete: on_complete) do internal_stream_react_component(component_name, ) end end |