Skip to content
Merged
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
29 changes: 17 additions & 12 deletions lib/assets/javascripts/react_ujs.js.erb
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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];
Expand All @@ -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];
Expand Down Expand Up @@ -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()});
}
}

Expand Down
6 changes: 5 additions & 1 deletion test/dummy/app/views/pages/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,8 @@
<li><%= link_to 'Alice', page_path(:id => 0) %></li>
<li><%= link_to 'Bob', page_path(:id => 1) %></li>
</ul>
<%= react_component 'HelloMessage', :name => @name %>
<div id='test-component'>
<%= react_component 'HelloMessage', :name => @name %>
</div>
<a href='#' onClick="ReactRailsUJS.unmountComponents('#test-component')">Unmount at #test-component</a>
<a href='#' onClick="ReactRailsUJS.mountComponents('#test-component')">Mount at #test-component</a>
21 changes: 16 additions & 5 deletions test/view_helper_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -115,13 +115,24 @@ class ViewHelperTest < ActionDispatch::IntegrationTest
assert page.has_content?('Hello Bob')
end

test 'react_ujs can unount at node' do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unmount

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)
Expand Down