From 6441fccf410dc9400727c09035974b37a6366801 Mon Sep 17 00:00:00 2001 From: Joshua Clark Date: Tue, 30 Aug 2016 18:02:27 -0400 Subject: [PATCH] WIP --- lib/assets/javascripts/react_ujs_mount.js | 30 +++++++++++++++++++++-- lib/react/rails/component_mount.rb | 3 +++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/lib/assets/javascripts/react_ujs_mount.js b/lib/assets/javascripts/react_ujs_mount.js index 141ac1663..b3bb25499 100644 --- a/lib/assets/javascripts/react_ujs_mount.js +++ b/lib/assets/javascripts/react_ujs_mount.js @@ -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) { @@ -77,6 +80,8 @@ 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 + "'" @@ -84,7 +89,7 @@ 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); } } }, @@ -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); diff --git a/lib/react/rails/component_mount.rb b/lib/react/rails/component_mount.rb index 7864773b3..d18f7a435 100644 --- a/lib/react/rails/component_mount.rb +++ b/lib/react/rails/component_mount.rb @@ -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