@@ -11,12 +11,16 @@ class ComponentMount
1111 attr_accessor :output_buffer
1212 mattr_accessor :camelize_props_switch
1313
14- # ControllerLifecycle calls these hooks
14+ # { ControllerLifecycle} calls these hooks
1515 # You can use them in custom helper implementations
16- def setup ( env )
16+ def setup ( controller )
17+ @controller = controller
1718 end
1819
19- def teardown ( env )
20+ def teardown ( controller )
21+ if controller . __prerenderer
22+ React ::ServerRendering . checkin_renderer ( controller . __prerenderer )
23+ end
2024 end
2125
2226 # Render a UJS-type HTML tag annotated with data attributes, which
@@ -30,7 +34,7 @@ def react_component(name, props = {}, options = {}, &block)
3034
3135 prerender_options = options [ :prerender ]
3236 if prerender_options
33- block = Proc . new { concat React :: ServerRendering . render ( name , props , prerender_options ) }
37+ block = Proc . new { concat ( prerender_component ( name , props , prerender_options ) ) }
3438 end
3539
3640 html_options = options . reverse_merge ( :data => { } )
@@ -47,6 +51,30 @@ def react_component(name, props = {}, options = {}, &block)
4751
4852 content_tag ( html_tag , '' , html_options , &block )
4953 end
54+
55+ module ControllerHelpers
56+ extend ActiveSupport ::Concern
57+
58+ included do
59+ # An instance of a server renderer, for use during this request
60+ attr_accessor :__prerenderer
61+ end
62+
63+ # If you want a per-request renderer, add this method as a before-action
64+ #
65+ # @example Having one renderer instance for each controller action
66+ # before_action :checkout_renderer
67+ def checkout_prerenderer
68+ self . __prerenderer = React ::ServerRendering . checkout_renderer
69+ end
70+ end
71+
72+ private
73+
74+ def prerender_component ( component_name , props , prerender_options )
75+ renderer = @controller . try ( :__prerenderer ) || React ::ServerRendering
76+ renderer . render ( component_name , props , prerender_options )
77+ end
5078 end
5179 end
5280end
0 commit comments