diff --git a/lib/react/rails/view_helper.rb b/lib/react/rails/view_helper.rb index 992659230..0a6041b14 100644 --- a/lib/react/rails/view_helper.rb +++ b/lib/react/rails/view_helper.rb @@ -9,7 +9,7 @@ def react_component(name, props = {}, options = {}, &block) prerender_options = options[:prerender] if prerender_options - block = Proc.new{ concat React::ServerRendering.render(name, props.merge(prerender: prerender_options)) } + block = Proc.new{ concat React::ServerRendering.render(name, props, prerender_options) } end html_options = options.reverse_merge(:data => {}) diff --git a/lib/react/server_rendering.rb b/lib/react/server_rendering.rb index 050ad4d16..c379be1ae 100644 --- a/lib/react/server_rendering.rb +++ b/lib/react/server_rendering.rb @@ -11,9 +11,9 @@ def self.reset_pool @@pool = ConnectionPool.new(options) { create_renderer } end - def self.render(component_name, props) + def self.render(component_name, props, prerender_options) @@pool.with do |renderer| - renderer.render(component_name, props) + renderer.render(component_name, props, prerender_options) end end diff --git a/lib/react/server_rendering/sprockets_renderer.rb b/lib/react/server_rendering/sprockets_renderer.rb index 94682bd43..129285377 100644 --- a/lib/react/server_rendering/sprockets_renderer.rb +++ b/lib/react/server_rendering/sprockets_renderer.rb @@ -14,13 +14,13 @@ def initialize(options={}) @context = ExecJS.compile(js_code) end - def render(component_name, props) + def render(component_name, props, prerender_options) # pass prerender: :static to use renderToStaticMarkup - if props.is_a?(Hash) && props[:prerender] == :static - react_render_method = "renderToStaticMarkup" - else - react_render_method = "renderToString" - end + react_render_method = if prerender_options == :static + "renderToStaticMarkup" + else + "renderToString" + end if !props.is_a?(String) props = props.to_json diff --git a/test/react/rails/view_helper_test.rb b/test/react/rails/view_helper_test.rb index 7624b3c2f..22b431233 100644 --- a/test/react/rails/view_helper_test.rb +++ b/test/react/rails/view_helper_test.rb @@ -40,6 +40,19 @@ class ViewHelperTest < ActionDispatch::IntegrationTest end end + test 'react_component accepts string props with prerender: true' do + html = @helper.react_component('Todo', {todo: 'render on the server'}.to_json, prerender: true) + assert(html.include?('data-react-class="Todo"'), "it includes attrs for UJS") + assert(html.include?('>render on the server'), "it includes rendered HTML") + assert(html.include?('data-reactid'), "it includes React properties") + end + + test 'react_component passes :static to SprocketsRenderer' do + html = @helper.react_component('Todo', {todo: 'render on the server'}.to_json, prerender: :static) + assert(html.include?('>render on the server'), "it includes rendered HTML") + assert(!html.include?('data-reactid'), "it DOESNT INCLUDE React properties") + end + test 'react_component accepts HTML options and HTML tag' do assert @helper.react_component('Foo', {}, :span).match(/<\/span>/) diff --git a/test/react/server_rendering/sprockets_renderer_test.rb b/test/react/server_rendering/sprockets_renderer_test.rb index 0b39636b8..5629fd92d 100644 --- a/test/react/server_rendering/sprockets_renderer_test.rb +++ b/test/react/server_rendering/sprockets_renderer_test.rb @@ -6,24 +6,24 @@ class SprocketsRendererTest < ActiveSupport::TestCase end test '#render returns HTML' do - result = @renderer.render("Todo", {todo: "write tests"}) + result = @renderer.render("Todo", {todo: "write tests"}, nil) assert_match(//, result) assert_match(/data-react-checksum/, result) end test '#render accepts strings' do - result = @renderer.render("Todo", {todo: "write more tests"}.to_json) + result = @renderer.render("Todo", {todo: "write more tests"}.to_json, nil) assert_match(//, result) end - test '#render accepts prerender: :static' do - result = @renderer.render("Todo", {todo: "write more tests", prerender: :static}) + test '#render accepts :static pre-render option' do + result = @renderer.render("Todo", {todo: "write more tests"}, :static) assert_match(/
  • write more tests<\/li>/, result) assert_no_match(/data-react-checksum/, result) end test '#render replays console messages' do - result = @renderer.render("TodoListWithConsoleLog", {todos: ["log some messages"]}) + result = @renderer.render("TodoListWithConsoleLog", {todos: ["log some messages"]}, nil) assert_match(/console.log.apply\(console, \["got initial state"\]\)/, result) assert_match(/console.warn.apply\(console, \["mounted component"\]\)/, result) assert_match(/console.error.apply\(console, \["rendered!","foo"\]\)/, result) @@ -31,7 +31,7 @@ class SprocketsRendererTest < ActiveSupport::TestCase test '#render console messages can be disabled' do no_log_renderer = React::ServerRendering::SprocketsRenderer.new({replay_console: false}) - result = no_log_renderer.render("TodoListWithConsoleLog", {todos: ["log some messages"]}) + result = no_log_renderer.render("TodoListWithConsoleLog", {todos: ["log some messages"]}, nil) assert_no_match(/console.log.apply\(console, \["got initial state"\]\)/, result) assert_no_match(/console.warn.apply\(console, \["mounted component"\]\)/, result) assert_no_match(/console.error.apply\(console, \["rendered!","foo"\]\)/, result) @@ -39,7 +39,7 @@ class SprocketsRendererTest < ActiveSupport::TestCase test '#render errors include stack traces' do err = assert_raises React::ServerRendering::SprocketsRenderer::PrerenderError do - @renderer.render("NonExistentComponent", {}) + @renderer.render("NonExistentComponent", {}, nil) end assert_match(/ReferenceError/, err.to_s) assert_match(/NonExistentComponent/, err.to_s, "it names the component") @@ -48,9 +48,9 @@ class SprocketsRendererTest < ActiveSupport::TestCase test '.new accepts any filenames' do limited_renderer = React::ServerRendering::SprocketsRenderer.new(files: ["react.js", "components/Todo.js"]) - assert_match(/get a real job<\/li>/, limited_renderer.render("Todo", {todo: "get a real job"})) + assert_match(/get a real job<\/li>/, limited_renderer.render("Todo", {todo: "get a real job"}, nil)) err = assert_raises React::ServerRendering::SprocketsRenderer::PrerenderError do - limited_renderer.render("TodoList", {todos: []}) + limited_renderer.render("TodoList", {todos: []}, nil) end assert_match(/ReferenceError/, err.to_s, "it doesnt load other files") end diff --git a/test/react/server_rendering_test.rb b/test/react/server_rendering_test.rb index a8a3b1fde..2574fc58e 100644 --- a/test/react/server_rendering_test.rb +++ b/test/react/server_rendering_test.rb @@ -6,8 +6,8 @@ def initialize(options) @name = options end - def render(component_name, props) - "#{@name} rendered #{component_name} with #{props}" + def render(component_name, props, prerender_options) + "#{@name} rendered #{component_name} with #{props} and #{prerender_options}" end end @@ -23,6 +23,7 @@ class ReactServerRenderingTest < ActiveSupport::TestCase teardown do React::ServerRendering.renderer = @previous_renderer React::ServerRendering.renderer_options = @previous_options + React::ServerRendering.reset_pool end test '.create_renderer makes a renderer with initialization options' do @@ -36,20 +37,20 @@ class ReactServerRenderingTest < ActiveSupport::TestCase test '.render returns a rendered string' do props = {"props" => true} - result = React::ServerRendering.render("MyComponent", props) - assert_equal("TEST rendered MyComponent with #{props}", result) + result = React::ServerRendering.render("MyComponent", props, "prerender-opts") + assert_equal("TEST rendered MyComponent with #{props} and prerender-opts", result) end test '.reset_pool forgets old renderers' do # At first, they use the first options: - assert_match(/^TEST/, React::ServerRendering.render(nil, nil)) - assert_match(/^TEST/, React::ServerRendering.render(nil, nil)) + assert_match(/^TEST/, React::ServerRendering.render(nil, nil, nil)) + assert_match(/^TEST/, React::ServerRendering.render(nil, nil, nil)) # Then change the init options and clear the pool: React::ServerRendering.renderer_options = "DIFFERENT" React::ServerRendering.reset_pool # New renderers are created with the new init options: - assert_match(/^DIFFERENT/, React::ServerRendering.render(nil, nil)) - assert_match(/^DIFFERENT/, React::ServerRendering.render(nil, nil)) + assert_match(/^DIFFERENT/, React::ServerRendering.render(nil, nil, nil)) + assert_match(/^DIFFERENT/, React::ServerRendering.render(nil, nil, nil)) end end \ No newline at end of file