diff --git a/CHANGELOG.md b/CHANGELOG.md index 0022c981a9..0b1ce8cdab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ Changes since last non-beta release. *Please add entries here for your pull requests that are not yet released.* +- Fixed race condition where a react component could attempt to initialize before it had been registered. [PR 1540](https://github.com/shakacode/react_on_rails/pull/1540) by [judahmeek](https://github.com/judahmeek) + ### [13.3.4] - 2022-05-23 ### Added diff --git a/node_package/src/clientStartup.ts b/node_package/src/clientStartup.ts index f4aae5517f..375e610a74 100644 --- a/node_package/src/clientStartup.ts +++ b/node_package/src/clientStartup.ts @@ -286,6 +286,17 @@ function isWindow(context: Context): context is Window { return (context as Window).document !== undefined; } +function onPageReady(callback: () => void) { + if (document.readyState === "complete") { + callback(); + } else { + document.addEventListener("readystatechange", function onReadyStateChange() { + onPageReady(callback); + document.removeEventListener("readystatechange", onReadyStateChange); + }); + } +} + export function clientStartup(context: Context): void { // Check if server rendering if (!isWindow(context)) { @@ -302,16 +313,5 @@ export function clientStartup(context: Context): void { // eslint-disable-next-line no-underscore-dangle, no-param-reassign context.__REACT_ON_RAILS_EVENT_HANDLERS_RAN_ONCE__ = true; - debugTurbolinks('Adding DOMContentLoaded event to install event listeners.'); - - // So long as the document is not loading, we can assume: - // The document has finished loading and the document has been parsed - // but sub-resources such as images, stylesheets and frames are still loading. - // If lazy asynch loading is used, such as with loadable-components, then the init - // function will install some handler that will properly know when to do hyrdation. - if (document.readyState !== 'loading') { - window.setTimeout(renderInit); - } else { - document.addEventListener('DOMContentLoaded', renderInit); - } + onPageReady(renderInit); } diff --git a/spec/dummy/app/views/layouts/application.html.erb b/spec/dummy/app/views/layouts/application.html.erb index 587795ef31..ca89d84d47 100644 --- a/spec/dummy/app/views/layouts/application.html.erb +++ b/spec/dummy/app/views/layouts/application.html.erb @@ -10,7 +10,7 @@ <%= yield :head %> - <%= javascript_pack_tag('client-bundle', 'data-turbolinks-track': true, defer: false) %> + <%= javascript_pack_tag('client-bundle', 'data-turbolinks-track': true) %> <%= csrf_meta_tags %> diff --git a/spec/dummy/config/initializers/react_on_rails.rb b/spec/dummy/config/initializers/react_on_rails.rb index 234a4ea999..8f3f247cc5 100644 --- a/spec/dummy/config/initializers/react_on_rails.rb +++ b/spec/dummy/config/initializers/react_on_rails.rb @@ -36,5 +36,4 @@ def self.adjust_props_for_client_side_hydration(component_name, props) config.rendering_props_extension = RenderingPropsExtension config.components_subdirectory = "startup" config.auto_load_bundle = true - config.defer_generated_component_packs = false end diff --git a/spec/dummy/spec/helpers/react_on_rails_helper_spec.rb b/spec/dummy/spec/helpers/react_on_rails_helper_spec.rb index 3ff4a9414f..dbe901ea74 100644 --- a/spec/dummy/spec/helpers/react_on_rails_helper_spec.rb +++ b/spec/dummy/spec/helpers/react_on_rails_helper_spec.rb @@ -42,7 +42,7 @@ class PlainReactOnRailsHelper allow(helper).to receive(:append_javascript_pack_tag) allow(helper).to receive(:append_stylesheet_pack_tag) expect { helper.load_pack_for_generated_component("component_name") }.not_to raise_error - expect(helper).to have_received(:append_javascript_pack_tag).with("generated/component_name", { defer: false }) + expect(helper).to have_received(:append_javascript_pack_tag).with("generated/component_name", { defer: true }) expect(helper).to have_received(:append_stylesheet_pack_tag).with("generated/component_name") end end