react-rails icon indicating copy to clipboard operation
react-rails copied to clipboard

Components aren't mounted on turbolinks cache

Open joshleblanc opened this issue 5 years ago • 10 comments

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.

1oumczyorq

joshleblanc avatar Jan 25 '19 19:01 joshleblanc

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.

BookOfGreg avatar Jan 29 '19 09:01 BookOfGreg

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.

joshleblanc avatar Jan 29 '19 22:01 joshleblanc

I’m working on a PR for this and support for data-turbolinks-permanent.

joshleblanc avatar Feb 01 '19 20:02 joshleblanc

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>

n8ta avatar Jul 10 '19 15:07 n8ta

@HorizonShadow 's PR should be released in React_UJS 2.6.0 now.

BookOfGreg avatar Aug 10 '19 21:08 BookOfGreg

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 Alt Text

sdb1228 avatar Jul 01 '20 13:07 sdb1228

@n8ta Any idea why this works?

bighitbiker3 avatar Jul 30 '20 16:07 bighitbiker3

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.

joshleblanc avatar Jul 30 '20 16:07 joshleblanc

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.

ksweetie avatar Nov 09 '20 14:11 ksweetie

https://github.com/mendelk/react-rails/commit/018812ca5de9963a8354f934230499c770e45377

worked for me.

Hampei avatar Nov 17 '20 14:11 Hampei

The issue is resolved as per the above discussion. Closing it.

alkesh26 avatar Nov 03 '22 09:11 alkesh26