Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Components don't re-mount after Turbolinks navigation #27

Open
phil-monroe opened this issue Mar 29, 2017 · 15 comments
Open

Components don't re-mount after Turbolinks navigation #27

phil-monroe opened this issue Mar 29, 2017 · 15 comments

Comments

@phil-monroe
Copy link

According to this line a react component will only mount if the innerHTML is empty.

// javascript/webpacker_react-npm-module/src/index.js:72
if (node.innerHTML.length === 0) this.render(node, component)

This works well for initial page loads that are not rendered via the Turbolinks cache, but components will not re-mount after navigating around an app that utilize Turbolinks caching. This can be replicated with the following steps:

  1. Use react_component on page one which mount's just fine.
  2. Click link to visit page two. page one's html is cached, the component is unmounted and page two is rendered.
  3. Click the back button, page one is rendered from the Turbolinks cache and the component will not be re-mounted as the components innerHTML is not empty

This is not noticeable for simple components that render static text, but becomes immediately apparent if a component that changes state over time (showing the current time, polling for new data, etc.).

Is there a reason for ensuring innerHTML is empty before mounting a component? Or perhaps the components should be un-mounted on turbolinks:before-cache to avoid being cached all together?

@renchap
Copy link
Owner

renchap commented Mar 30, 2017

Thanks for the report @phil-monroe!

@sevos do you remember why this check was needed?

@ghost
Copy link

ghost commented Apr 10, 2017

Hi, I'm new to React and I'm trying to render a component in my layout file. I'm not sure if this issue is related to what I'm facing. The components do render when I visit different links but I'm getting the following error every time I visit another link:

unmountComponentAtNode(): The node you're attempting to unmount was rendered by another copy of React.

In my layout file, I am rendering a simple component:

/ application.html.slim
/ left out some code...
= javascript_pack_tag 'admin'
= react_component('Header')

Here's in the root pack that I'm calling:

// app/javascript/packs/root_pack.js
import Header from './header/header';
import Turbolinks from 'turbolinks';
Turbolinks.start();

WebpackerReact.setup({Header});

Obviously, the error disappears when I remove turbolinks. I think that it's great having it there, I feel that the page loads sluggishly without it ;)

Appreciate the help!

@sevos
Copy link
Contributor

sevos commented Apr 10, 2017

What versions of the gem and npm package are you using? @igikorn

@sevos
Copy link
Contributor

sevos commented Apr 10, 2017

@renchap I have no idea why we have this line there. Imho it shouldn't be there, but I may be wrong.

@ghost
Copy link

ghost commented Apr 10, 2017

@sevos Thanks for the reply!

Yarn

"webpack": "^2.3.3",
"webpack-dev-server": "^2.4.2",
"webpack-manifest-plugin": "^1.1.0",
"webpack-merge": "^4.1.0",
"webpacker-react": "^0.2.1"

Gemfile

webpacker (1.1)
webpacker-react (0.2.0)

@sevos
Copy link
Contributor

sevos commented Apr 10, 2017

Could you please provide a minimum repository reproducing the problem? I will take a second look in the evening

@ghost
Copy link

ghost commented Apr 10, 2017

Hi @sevos, I've reproduced the issue in a minimum repository:

https://github.com/igikorn/webpacker-react-turbolinks

Thank you very much!

@ghost
Copy link

ghost commented Apr 22, 2017

Hi @sevos any luck with this? Appreciate the help!

@justin808
Copy link

@igikorn can you tell me if https://github.com/shakacode/react_on_rails has the same Turbolinks issue?

@iozeey
Copy link

iozeey commented Feb 9, 2018

Hi,

Uncaught Error: Cannot find module "turbolinks"

This app is really helpful. I am facing an issue with turbolinks adding to component.

import Hello from 'components/hello'
import WebpackerReact from 'webpacker-react'
// import Turbolinks from 'turbolinks'

// Turbolinks.start()

WebpackerReact.setup({Hello})

Thanks

@BookOfGreg
Copy link

@zeeshan-za-ahmad @renchap
I think I can help with this one.
I released a new version of react_UJS (The NPM module) that fixes a Turbolinks 5 issue.
reactjs/react-rails#868

I've released it as the --pre tag waiting on a JQuery confirmation but this may fix your issue.

@justin808 It's rude to go into other people's repos and pitch your gem, please try to HELP people if you're visiting other projects.

@gafemoyano
Copy link

gafemoyano commented May 4, 2018

Hey, I've bumped into this issue as well.
For me, I found that the easiest way to handle this is to just let turbolinks know that it shouldn't cache pages that include React components with state by including something like

<% content_for :head do %>
  <meta name="turbolinks-cache-control" content="no-cache">
<% end %>
<%= react_component('Component', data: @data) %>

So this way the navigation still occurss with turbolinks, but it won't display a cached versions of the page (which renders the components Html but isn't handled by React AFAIK) bur rather hit the server and re mount the components just like on first visit.

@MindRave
Copy link

MindRave commented May 25, 2018

Any news on this issue? I've tried the "no-cache" approach but it won't work for me. Emptied the cache, still nothing. The component just won't mount after a Turbolinks navigation. 😕

EDIT: seems to be working when I use ReactRailsUJS.detectEvents() (after useContext in my case).

@gafemoyano
Copy link

You could try disabling Turbolinks Page cache globally, and see if the cache is actually the reason why your react component is not getting mounted.

<meta name="turbolinks-cache-control" content="no-cache">

@BookOfGreg
Copy link

Someone just needs to port over the detection fixes from React_UJS to this NPM package.
reactjs/react-rails#868

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants