@@ -17,8 +17,6 @@ module Helper
1717 include ReactOnRails ::Utils ::Required
1818
1919 COMPONENT_HTML_KEY = "componentHtml"
20- ADD_COMPONENT_TO_PENDING_HYDRATION_FUNCTION = "$ROR_PC"
21- ADD_STORE_TO_PENDING_HYDRATION_FUNCTION = "$ROR_PS"
2220
2321 # react_component_name: can be a React function or class component or a "Render-Function".
2422 # "Render-Functions" differ from a React function in that they take two parameters, the
@@ -126,6 +124,7 @@ def react_component(component_name, options = {})
126124 # @option options [Boolean] :raise_on_prerender_error Set to true to raise exceptions during server-side rendering
127125 # Any other options are passed to the content tag, including the id.
128126 def stream_react_component ( component_name , options = { } )
127+ options = options . merge ( force_load : true ) unless options . key? ( :force_load )
129128 run_stream_inside_fiber do
130129 internal_stream_react_component ( component_name , options )
131130 end
@@ -195,9 +194,12 @@ def react_component_hash(component_name, options = {})
195194 # props: Ruby Hash or JSON string which contains the properties to pass to the redux store.
196195 # Options
197196 # defer: false -- pass as true if you wish to render this below your component.
198- def redux_store ( store_name , props : { } , defer : false )
197+ # force_load: false -- pass as true if you wish to hydrate this store immediately instead of
198+ # waiting for the page to load.
199+ def redux_store ( store_name , props : { } , defer : false , force_load : false )
199200 redux_store_data = { store_name : store_name ,
200- props : props }
201+ props : props ,
202+ force_load : force_load }
201203 if defer
202204 registered_stores_defer_render << redux_store_data
203205 "YOU SHOULD NOT SEE THIS ON YOUR VIEW -- Uses as a code block, like <% redux_store %> " \
@@ -463,7 +465,7 @@ def build_react_component_result_for_server_rendered_string(
463465
464466 result_console_script = render_options . replay_console ? console_script : ""
465467 result = compose_react_component_html_with_spec_and_console (
466- component_specification_tag , rendered_output , result_console_script , render_options . dom_id
468+ component_specification_tag , rendered_output , result_console_script
467469 )
468470
469471 prepend_render_rails_context ( result )
@@ -529,20 +531,13 @@ def build_react_component_result_for_server_rendered_hash(
529531 )
530532 end
531533
532- def compose_react_component_html_with_spec_and_console ( component_specification_tag , rendered_output , console_script , dom_id = nil )
533- hydrate_script = if dom_id . present?
534- add_component_to_pending_hydration_code = "window.#{ ADD_COMPONENT_TO_PENDING_HYDRATION_FUNCTION } ('#{ dom_id } ');"
535- content_tag ( :script , add_component_to_pending_hydration_code . html_safe )
536- else
537- ""
538- end
539-
534+ def compose_react_component_html_with_spec_and_console ( component_specification_tag , rendered_output ,
535+ console_script )
540536 # IMPORTANT: Ensure that we mark string as html_safe to avoid escaping.
541537 html_content = <<~HTML
542538 #{ rendered_output }
543539 #{ component_specification_tag }
544540 #{ console_script }
545- #{ hydrate_script }
546541 HTML
547542 html_content . strip . html_safe
548543 end
@@ -554,30 +549,10 @@ def rails_context_if_not_already_rendered
554549
555550 @rendered_rails_context = true
556551
557- rails_context_tag = content_tag ( :script ,
558- json_safe_and_pretty ( data ) . html_safe ,
559- type : "application/json" ,
560- id : "js-react-on-rails-context" )
561-
562- pending_hydration_script = <<~JS . strip_heredoc
563- window.REACT_ON_RAILS_PENDING_COMPONENT_DOM_IDS = [];
564- window.REACT_ON_RAILS_PENDING_STORE_NAMES = [];
565- window.#{ ADD_COMPONENT_TO_PENDING_HYDRATION_FUNCTION } = function(domId) {
566- window.REACT_ON_RAILS_PENDING_COMPONENT_DOM_IDS.push(domId);
567- if (window.ReactOnRails) {
568- window.ReactOnRails.renderOrHydrateLoadedComponents();
569- }
570- };
571- window.#{ ADD_STORE_TO_PENDING_HYDRATION_FUNCTION } = function(storeName) {
572- window.REACT_ON_RAILS_PENDING_STORE_NAMES.push(storeName);
573- if (window.ReactOnRails) {
574- window.ReactOnRails.hydratePendingStores();
575- }
576- };
577- JS
578- rails_context_tag . concat (
579- content_tag ( :script , pending_hydration_script . html_safe )
580- ) . html_safe
552+ content_tag ( :script ,
553+ json_safe_and_pretty ( data ) . html_safe ,
554+ type : "application/json" ,
555+ id : "js-react-on-rails-context" )
581556 end
582557
583558 # prepend the rails_context if not yet applied
@@ -606,7 +581,7 @@ def internal_react_component(react_component_name, options = {})
606581 "data-trace" => ( render_options . trace ? true : nil ) ,
607582 "data-dom-id" => render_options . dom_id ,
608583 "data-store-dependencies" => render_options . store_dependencies . to_json ,
609- )
584+ "data-force-load" => ( render_options . force_load ? true : nil ) )
610585
611586 if render_options . force_load
612587 component_specification_tag . concat (
@@ -629,16 +604,21 @@ def internal_react_component(react_component_name, options = {})
629604
630605 def render_redux_store_data ( redux_store_data )
631606 store_hydration_data = content_tag ( :script ,
632- json_safe_and_pretty ( redux_store_data [ :props ] ) . html_safe ,
633- type : "application/json" ,
634- "data-js-react-on-rails-store" => redux_store_data [ :store_name ] . html_safe )
635- hydration_code = "window.#{ ADD_STORE_TO_PENDING_HYDRATION_FUNCTION } ('#{ redux_store_data [ :store_name ] } ');"
636- store_hydration_script = content_tag ( :script , hydration_code . html_safe )
637-
638- prepend_render_rails_context <<~HTML
639- #{ store_hydration_data }
640- #{ store_hydration_script }
641- HTML
607+ json_safe_and_pretty ( redux_store_data [ :props ] ) . html_safe ,
608+ type : "application/json" ,
609+ "data-js-react-on-rails-store" => redux_store_data [ :store_name ] . html_safe ,
610+ "data-force-load" => ( redux_store_data [ :force_load ] ? true : nil ) )
611+
612+ if redux_store_data [ :force_load ]
613+ store_hydration_data . concat (
614+ content_tag ( :script , <<~JS . strip_heredoc . html_safe
615+ ReactOnRails.reactOnRailsStoreLoaded('#{ redux_store_data [ :store_name ] } ');
616+ JS
617+ )
618+ )
619+ end
620+
621+ prepend_render_rails_context ( store_hydration_data )
642622 end
643623
644624 def props_string ( props )
@@ -738,7 +718,9 @@ def initialize_redux_stores(render_options)
738718 return result unless store_dependencies . present?
739719
740720 declarations = +"var reduxProps, store, storeGenerator;\n "
741- store_objects = registered_stores_including_deferred . select { |store | store_dependencies . include? ( store [ :store_name ] ) }
721+ store_objects = registered_stores_including_deferred . select do |store |
722+ store_dependencies . include? ( store [ :store_name ] )
723+ end
742724
743725 result << store_objects . each_with_object ( declarations ) do |redux_store_data , memo |
744726 store_name = redux_store_data [ :store_name ]
0 commit comments