Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 28 additions & 2 deletions lib/assets/javascripts/react_ujs_mount.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
// example: `data-react-props="{\"item\": { \"id\": 1, \"name\": \"My Item\"} }"`
PROPS_ATTR: 'data-react-props',

REACT_ATTR: 'data-react-name',
REACT_DOM_ATTR: 'data-react-dom-name',

// helper method for the mount and unmount methods to find the
// `data-react-class` DOM elements
findDOMNodes: function(searchSelector) {
Expand Down Expand Up @@ -77,14 +80,16 @@
var constructor = this.getConstructor(className);
var propsJson = node.getAttribute(window.ReactRailsUJS.PROPS_ATTR);
var props = propsJson && JSON.parse(propsJson);
var reactDomInstance = getReactDomInstanceAtNode(node);
var reactInstance = getReactInstanceAtNode(node);

if (typeof(constructor) === "undefined") {
var message = "Cannot find component: '" + className + "'"
if (console && console.log) { console.log("%c[react-rails] %c" + message + " for element", "font-weight: bold", "", node) }
var error = new Error(message + ". Make sure your component is globally available to render.")
throw error
} else {
ReactDOM.render(React.createElement(constructor, props), node);
reactDomInstance.render(reactInstance.createElement(constructor, props), node);
}
}
},
Expand All @@ -96,9 +101,30 @@

for (var i = 0; i < nodes.length; ++i) {
var node = nodes[i];
var reactDomInstance = getReactDomInstanceAtNode(node);

ReactDOM.unmountComponentAtNode(node);
reactDomInstance.unmountComponentAtNode(node);
}
}
};

function getReactDomInstanceAtNode(node) {
var reactDomProp = node.getAttribute(window.ReactRailsUJS.REACT_DOM_ATTR);

try {
return window[reactDomProp] || eval.call(window, reactDomProp);
} catch {
return ReactDOM;
}
}

function getReactInstanceAtNode(node) {
var reactProp = node.getAttribute(window.ReactRailsUJS.REACT_ATTR);

try {
return window[reactProp] || eval.call(window, reactProp);
} catch {
return React;
}
}
})(document, window);
3 changes: 3 additions & 0 deletions lib/react/rails/component_mount.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ def react_component(name, props = {}, options = {}, &block)
html_options[:data].tap do |data|
data[:react_class] = name
data[:react_props] = (props.is_a?(String) ? props : props.to_json)

data[:react_name] = options[:react_name]
data[:react_dom_name] = options[:react_dom_name]
end
end
html_tag = html_options[:tag] || :div
Expand Down