react-rails
react-rails copied to clipboard
Components aren't mounted on turbolinks cache
Help us help you! Have you looked for similar issues? Do you have reproduction steps? Contributing Guide
Steps to reproduce
Place a component on your page. Navigation to that page, then to another, then back to the page with the component.
In the period between turbolinks showing you the cached page, and fetching the new one, no components are mounted.
Expected behavior
The cached page should at least show the component. If remounting it temporarily has too many side effect. I know stimulus just mounts and unmounts it as the cache is replaced.
Actual behavior
The components don't show up at all. There's just empty space.
System configuration
Sprockets or Webpacker version: 3.5 React-Rails version: 2.4 Rect_UJS version: 2.4.4 Rails version: 5.2.2 Ruby version: 2.4.5
I'm not actually sure if I should be posting this here or over at turbolinks, but seeing as not even data-turbolinks-permanent
, I feel like it must be something react-rails is doing.
If you render a component, navigate away, and navigate back, the component is gone until turbolinks finishes loading. Even if the component has a data-turbolinks-permanent tag, or if its parent has it. The component just doesn't exist.
So if I have a slow page load, I end up with many seconds of elements just... not there. It's not very pretty.
Here's a gif of what I mean. After navigation back to the first page, the table doesn't mount.
https://github.com/reactjs/react-rails/blob/master/react_ujs/src/events/turbolinks.js It's probably not handling all the turbolinks state changes. Can you identify the turbolinks events associated with the change or provide a small sample app for me to test?
Sometimes other libs such as turbolinks add new features and we don't know about them until someone like yourself lets us know so we can be a little slow off the mark in integrating them. It is possible for you to trigger a remount or to tag the HTML generated within react with relevant turbolinks tags manually though of course it's better for this gem to automatically do that if possible.
https://github.com/HorizonShadow/react-rails-turbolinks
I put a sleep in the root action, so if you go to localhost:3000, then click "Two", then click "Root", you'll see the root page for 2 seconds before mounting the Example component.
I played around with the turbolinks events, but couldn't get it to mount.
I’m working on a PR for this and support for data-turbolinks-permanent.
For future people who see this I had a same symptoms that I fixed by moving
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
the the last line of <head></head>
@HorizonShadow 's PR should be released in React_UJS 2.6.0 now.
Hey @joshleblanc @BookOfGreg Is there anything special here we need to add to get this to work? I am on ujs 2.6.1 right now and am still seeing the problem. I added permanent tag and id to my user icon like mentioned in the docs to see if I could get it to persist across page navigations but am still seeing problems like mentioned above
@n8ta Any idea why this works?
It's been forever since I looked at that, and I vaguely seem to recall part of it being rolled back due to other issues.
I'm not sure if it still works.
To re-render components immediately, I added:
document.addEventListener("turbolinks:render", function(event) {
ReactRailsUJS.mountComponents()
})
That avoids flickering when loading a cached page, but it ends up calling mountComponents
twice: once after rendering the cached version, and again after rendering the fresh version, which may or may not be what you want.
If anyone has a better workaround, I'd be interested.
https://github.com/mendelk/react-rails/commit/018812ca5de9963a8354f934230499c770e45377
worked for me.
The issue is resolved as per the above discussion. Closing it.