Created
June 28, 2019 06:12
-
-
Save maxim/d9f2ee902b7800c728136a08c49797d2 to your computer and use it in GitHub Desktop.
Extending react-rails with styled components support
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# config/initializers/react.rb | |
Rails.configuration.react.server_renderer = | |
Class.new(React::ServerRendering::BundleRenderer) do | |
private | |
def render_from_parts(before, main, after) | |
js_code = compose_js(before, main, after) | |
@context.eval(js_code) | |
end | |
def compose_js(before, main, after) | |
<<-JS | |
(function () { | |
#{before} | |
var data = #{main}; | |
var result = data['html']; | |
#{after} | |
return data; | |
})() | |
JS | |
end | |
end | |
Rails.configuration.react.view_helper_implementation = | |
Class.new(React::Rails::ComponentMount) do | |
def setup(*) | |
super.tap { init_component_styles } | |
end | |
private | |
def prerender_component(*) | |
data = super | |
case data | |
when Hash | |
register_component_style(data['styles']) | |
data['html'].html_safe | |
else | |
data.html_safe | |
end | |
end | |
def init_component_styles | |
@controller.instance_variable_set(:@styled_component_styles, '') | |
end | |
def register_component_style(style) | |
@controller.instance_variable_get(:@styled_component_styles) << style.to_s | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import ReactRailsUJS from 'react_ujs'; | |
import ReactDOMServer from 'react-dom/server'; | |
import { ServerStyleSheet } from 'styled-components'; | |
const componentRequireContext = require.context('components', true); | |
ReactRailsUJS.useContext(componentRequireContext); | |
ReactRailsUJS.serverRender = function(renderFunction, componentName, props) { | |
const ComponentConstructor = this.getConstructor(componentName); | |
const stylesheet = new ServerStyleSheet(); | |
const wrappedElement = stylesheet.collectStyles( | |
<ComponentConstructor {...props} />, | |
); | |
const html = ReactDOMServer[renderFunction](wrappedElement); | |
return { | |
html, | |
styles: stylesheet.getStyleTags(), | |
}; | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<#% put this line where you want styles to go %> | |
<%= raw @styled_component_styles.to_s %> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment