diff --git a/lib/assets/javascripts/react_ujs.js.erb b/lib/assets/javascripts/react_ujs.js.erb index e6bf8b269..1d2fabfa9 100644 --- a/lib/assets/javascripts/react_ujs.js.erb +++ b/lib/assets/javascripts/react_ujs.js.erb @@ -12,9 +12,14 @@ RAILS_ENV_DEVELOPMENT: <%= Rails.env == "development" %>, // helper method for the mount and unmount methods to find the // `data-react-class` DOM elements - findDOMNodes: function() { + findDOMNodes: function(searchSelector) { // we will use fully qualified paths as we do not bind the callbacks - var selector = '[' + window.ReactRailsUJS.CLASS_NAME_ATTR + ']'; + var selector; + if (typeof searchSelector === 'undefined') { + var selector = '[' + window.ReactRailsUJS.CLASS_NAME_ATTR + ']'; + } else { + var selector = searchSelector + ' [' + window.ReactRailsUJS.CLASS_NAME_ATTR + ']'; + } if ($) { return $(selector); @@ -23,8 +28,8 @@ } }, - mountComponents: function() { - var nodes = window.ReactRailsUJS.findDOMNodes(); + mountComponents: function(searchSelector) { + var nodes = window.ReactRailsUJS.findDOMNodes(searchSelector); for (var i = 0; i < nodes.length; ++i) { var node = nodes[i]; @@ -40,8 +45,8 @@ } }, - unmountComponents: function() { - var nodes = window.ReactRailsUJS.findDOMNodes(); + unmountComponents: function(searchSelector) { + var nodes = window.ReactRailsUJS.findDOMNodes(searchSelector); for (var i = 0; i < nodes.length; ++i) { var node = nodes[i]; @@ -77,17 +82,17 @@ console.warn('The Turbolinks cache has been disabled (Turbolinks >= 2.4.0 is recommended). See https://github.com/reactjs/react-rails/issues/87 for more information.'); } } - handleEvent('page:change', window.ReactRailsUJS.mountComponents); - handleEvent(unmountEvent, window.ReactRailsUJS.unmountComponents); + handleEvent('page:change', function() {window.ReactRailsUJS.mountComponents()}); + handleEvent(unmountEvent, function() {window.ReactRailsUJS.unmountComponents()}); } function handleNativeEvents() { if ($) { - $(window.ReactRailsUJS.mountComponents); - $(window).unload(window.ReactRailsUJS.unmountComponents); + $(function() {window.ReactRailsUJS.mountComponents()}); + $(window).unload(function() {window.ReactRailsUJS.unmountComponents()}); } else { - document.addEventListener('DOMContentLoaded', window.ReactRailsUJS.mountComponents); - window.addEventListener('unload', window.ReactRailsUJS.unmountComponents); + document.addEventListener('DOMContentLoaded', function() {window.ReactRailsUJS.mountComponents()}); + window.addEventListener('unload', function() {window.ReactRailsUJS.unmountComponents()}); } } diff --git a/test/dummy/app/views/pages/show.html.erb b/test/dummy/app/views/pages/show.html.erb index 2c7ac3dfe..404bc4b61 100644 --- a/test/dummy/app/views/pages/show.html.erb +++ b/test/dummy/app/views/pages/show.html.erb @@ -2,4 +2,8 @@
  • <%= link_to 'Alice', page_path(:id => 0) %>
  • <%= link_to 'Bob', page_path(:id => 1) %>
  • -<%= react_component 'HelloMessage', :name => @name %> +
    + <%= react_component 'HelloMessage', :name => @name %> +
    +Unmount at #test-component +Mount at #test-component diff --git a/test/view_helper_test.rb b/test/view_helper_test.rb index 23c061d43..2160a2304 100644 --- a/test/view_helper_test.rb +++ b/test/view_helper_test.rb @@ -48,21 +48,21 @@ class ViewHelperTest < ActionDispatch::IntegrationTest assert html.include?('class="test"') assert html.include?('data-foo="1"') end - + test 'ujs object present on the global React object and has our methods' do visit '/pages/1' assert page.has_content?('Hello Bob') - + # the exposed ujs object is present ujs_present = page.evaluate_script('typeof ReactRailsUJS === "object";') assert_equal(ujs_present, true) - + # it contains the constants class_name_present = page.evaluate_script('ReactRailsUJS.CLASS_NAME_ATTR === "data-react-class";') assert_equal(class_name_present, true) props_present = page.evaluate_script('ReactRailsUJS.PROPS_ATTR === "data-react-props";') assert_equal(props_present, true) - + #it contains the methods find_dom_nodes_present = page.evaluate_script('typeof ReactRailsUJS.findDOMNodes === "function";') assert_equal(find_dom_nodes_present, true) @@ -115,13 +115,24 @@ class ViewHelperTest < ActionDispatch::IntegrationTest assert page.has_content?('Hello Bob') end + test 'react_ujs can unount at node' do + visit '/pages/1' + assert page.has_content?('Hello Bob') + + page.click_link 'Unmount at #test-component' + assert page.has_no_content?('Hello Bob') + + page.click_link 'Mount at #test-component' + assert page.has_content?('Hello Bob') + end + test 'react server rendering also gets mounted on client' do visit '/server/1' assert_match(/data-react-class=\"TodoList\"/, page.html) assert_match(/data-react-checksum/, page.html) assert_match(/yep/, page.find("#status").text) end - + test 'react server rendering does not include internal properties' do visit '/server/1' assert_no_match(/tag=/, page.html)