Skip to content

Commit a80805c

Browse files
author
Robert Mosolgo
committed
Merge pull request #329 from garbles/add-component-renderer
Allow component inline rendering from controller
2 parents 0aeb167 + ca644a0 commit a80805c

File tree

6 files changed

+40
-0
lines changed

6 files changed

+40
-0
lines changed

lib/react/rails.rb

+1
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
require 'react/rails/railtie'
44
require 'react/rails/version'
55
require 'react/rails/view_helper'
6+
require 'react/rails/controller_renderer'
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
class React::Rails::ControllerRenderer
2+
include React::Rails::ViewHelper
3+
include ActionView::Helpers::TagHelper
4+
include ActionView::Helpers::TextHelper
5+
6+
attr_accessor :output_buffer
7+
8+
def self.call(*args, &block)
9+
new.call(*args, &block)
10+
end
11+
12+
def call(name, options, &block)
13+
props = options.fetch(:props, {})
14+
options = options.slice(:data, :tag).merge(prerender: true)
15+
react_component(name, props, options, &block)
16+
end
17+
end

lib/react/rails/railtie.rb

+8
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@ class Railtie < ::Rails::Railtie
3232
end
3333
end
3434

35+
initializer "react_rails.add_component_renderer", group: :all do |app|
36+
ActionController::Renderers.add :component do |component_name, options|
37+
html = ::React::Rails::ControllerRenderer.call(component_name, options)
38+
render_options = options.merge(inline: html)
39+
render(render_options)
40+
end
41+
end
42+
3543
initializer "react_rails.bust_cache", group: :all do |app|
3644
asset_variant = React::Rails::AssetVariant.new({
3745
variant: app.config.react.variant,

test/dummy/app/controllers/server_controller.rb

+4
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,8 @@ def console_example_suppressed
1414
React::ServerRendering.reset_pool
1515
@todos = %w{todo1 todo2 todo3}
1616
end
17+
18+
def inline_component
19+
render component: 'TodoList', props: { todos: [{todo: 'Render this inline'}] }, tag: 'span'
20+
end
1721
end

test/dummy/config/routes.rb

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
collection do
55
get :console_example
66
get :console_example_suppressed
7+
get :inline_component
78
end
89
end
910
end

test/server_rendered_html_test.rb

+9
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,13 @@ def wait_to_ensure_asset_pipeline_detects_changes
5151
assert_no_match(/console.warn/, response.body)
5252
assert_no_match(/console.error/, response.body)
5353
end
54+
55+
test 'react inline component rendering' do
56+
get '/server/inline_component'
57+
assert_match(/<span data-react-class=\"TodoList\"/, response.body)
58+
# make sure that the items are prerendered
59+
assert_match(/Render this inline<\/span>/, response.body)
60+
# make sure that the layout is rendered with the component
61+
assert_match(/<title>Dummy<\/title>/, response.body)
62+
end
5463
end

0 commit comments

Comments
 (0)