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.
237 238 239 240 241 242 243 244 245 246 247 248 249 |
# File 'app/helpers/react_on_rails_pro_helper.rb', line 237 def async_react_component(component_name, = {}) unless defined?() && raise ReactOnRailsPro::Error, "async_react_component requires AsyncRendering concern. " \ "Include ReactOnRailsPro::AsyncRendering in your controller and call enable_async_react_rendering." end task = .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
270 271 272 273 274 275 |
# File 'app/helpers/react_on_rails_pro_helper.rb', line 270 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_optionskey with a value of a hash including as :compress, :expires_in, :race_condition_ttl as documented in the Rails Guides -
Provide boolean values for
:ifor:unlessto conditionally use caching.
51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'app/helpers/react_on_rails_pro_helper.rb', line 51 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_optionskey with a value of a hash including as :compress, :expires_in, :race_condition_ttl as documented in the Rails Guides -
Provide boolean values for
:ifor:unlessto conditionally use caching.
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'app/helpers/react_on_rails_pro_helper.rb', line 78 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_optionskey with a value of a hash including as :compress, :expires_in, :race_condition_ttl as documented in the Rails Guides -
Provide boolean values for
:ifor:unlessto conditionally use caching.
213 214 215 216 217 218 |
# File 'app/helpers/react_on_rails_pro_helper.rb', line 213 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
11 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 |
# File 'app/helpers/react_on_rails_pro_helper.rb', line 11 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:
188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'app/helpers/react_on_rails_pro_helper.rb', line 188 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.
126 127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'app/helpers/react_on_rails_pro_helper.rb', line 126 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 = .merge(immediate_hydration: true) unless .key?(:immediate_hydration) # 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 |