【问题标题】:DOMContentLoaded not firing after navigation but fires on page reload when using javascript_pack_tagDOMContentLoaded 在导航后未触发,但在使用 javascript_pack_tag 时在页面重新加载时触发
【发布时间】:2019-09-28 21:14:37
【问题描述】:

我正在使用 React 和 Webpacker 处理 Rails 6 rc1 项目。

我目前正在使用javascript_pack_tag 在我的 Rails 应用程序中呈现 React 组件。我尽量不使用像 react-rails 这样的 gem,只是为了让事情变得简单。

今天我发现了一个奇怪的行为,即从链接导航到页面后,我的 React 组件不会呈现。但是,在页面重新加载时,我的组件会被渲染。

Gemfile:

gem 'rails', '~> 6.0.0.rc1'
gem 'pg', '>= 0.18', '< 2.0'
gem 'puma', '~> 3.11'
gem 'sass-rails', '~> 5'
gem 'webpacker', '~> 4.0'
gem 'turbolinks', '~> 5'
gem 'jbuilder', '~> 2.5'
gem 'bootsnap', '>= 1.4.2', require: false
gem 'devise', '~>4.6'

group :development, :test do
  gem 'pry-byebug'
  gem 'rspec-rails', '~> 3.8'
end

group :development do
  gem 'web-console', '>= 3.3.0'
  gem 'listen', '>= 3.0.5', '< 3.2'
  gem 'spring'
  gem 'spring-watcher-listen', '~> 2.0.0'
end

app/views/layouts/application.html.erb:

<html>
  <head>
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
....

app/javascript/packs/application.js:

require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")

import "bootstrap"
import "../stylesheets/application"

app/views/posts/new.html.erb:

<%= content_tag :div,
  id: 'post_data',
  data: @post do %>
<% end %>
<div id="render_here"></div>
<%= javascript_pack_tag 'new_post' %>

app/javascript/packs/new_post.jsx:(虽然这个文件中的 React 代码与问题无关)

import React from 'react';
import ReactDOM from 'react-dom';
import PostForm from '../components/PostForm';

document.addEventListener('DOMContentLoaded', () => {
  const node = document.getElementById('post_data');
  const data = JSON.parse(node.getAttribute('data'));
  const dom = document.querySelector('#render_here');

  ReactDOM.render(
    <PostForm post={data} />,
    dom);
});

使用此设置,在单击导航到页面的链接后不会呈现组件。在页面重新加载时,组件会被渲染。

我尝试了很多东西。

new_post.jsx 中,在注释掉所有内容并只留下console.log(document.readyState) 后,控制台会显示complete 两次。在页面加载时,它显示loading

然后我尝试在new_post.jsx中使用jQuery的document.ready

$(document).ready(function() {
  if (pageInitialized) {
    return;
  }
  pageInitialized = true;

  console.log('render');
...

同样,render 在页面导航到后显示两次。在页面重新加载时,render 会显示一次。

发生了什么事?

【问题讨论】:

  • 更新:我发现罪魁祸首是require("turbolinks").start()application.js 中。删除该行会使我的组件正确加载。

标签: javascript ruby-on-rails reactjs dom webpack


【解决方案1】:

我知道这已通过解决方法为您解决,但我在搜索相同问题时遇到了这个问题作为第一个结果,因此为了将来供遇到相同问题的其他人参考,我想留下一个解释.

如此处所述Rails 5: how to use $(document).ready() with turbo-links 更好的方法是监听 turbolinks 事件。

document.addEventListener("turbolinks:load", ()=> {
   alert("loaded");
}

或者如果你需要 jQuery

$( document ).on("turbolinks:load", ()=> {
    alert("loaded");
}

CoffeScript 变体:

document.addEventListener "turbolinks:load",  ->
    alert "loaded"

【讨论】:

  • 谢谢,这真的很有帮助。 @jules 提到的解决方法也对我有用,但更好地了解发生了什么,并且不需要禁用 turbolinks。
  • 谢谢!这也确实帮助了我。我在我的 RoR 应用程序中使用了第三方表构建器,但是这些表不是在导航时构建的,而是在刷新时构建的。将window.addEventListener('DOMContentLoaded', event =&gt; { 更改为window.addEventListener("turbolinks:load", event =&gt; { 解决了这个问题。感谢您的贡献!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-18
  • 1970-01-01
  • 1970-01-01
  • 2021-10-19
  • 1970-01-01
  • 1970-01-01
  • 2014-10-02
相关资源
最近更新 更多