-
Notifications
You must be signed in to change notification settings - Fork 759
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
turbolinks:before-render for unmounting causes warnings #607
Comments
Exact same issue here: It looks like it's related to Turbolinks cache. If cache is disabled, it fixes this issue:
|
I bet Turbolinks changes the whitespace when caching the content. I think the right thing to do is unmount before caching, as suggested by the OP. It will make it work, but we lose the nice UX of #521. Hmm, I'm not sure how to get both! |
I tried with before-cache, but as you mentioned UX is not as nice. Elements jump around a bit... |
I've been testing today without unmounting with Rails 5 and Turbolinks 5. It works like a charm, no warning and I can't find any issue. It looks like Trubolinks is doing the cleanup since it uses cloneNode(true) for caching. I am probably missing something, any reason why we have to unmount components here?
|
Imagine you have a React component for which, as long as it is mounted, it is pinging the server for updates. We need a way to stop the ping. Usually that's with Is there another way to address those issues? |
I see your point and it makes sense at some level. I am just wondering if this is the role of react-rails to take care of this case. It depends on which angle we are looking at this problem, but if you are building a SPA app, it is important to avoid memory leaks. But if you are not, it's not as important since the all page get flushed when browsing to the next page. Also, when using React framework directly it's up to the developer to call unmountComponentAtNode(), maybe it could be the same here. Either way is fine with me, I just wish we can find a clean way to unmount components without having to do it in before-cache. For event listeners cloneNode() doesn't copy event listeners has mention in the doc, so that should be OK. Thanks for your amazing work @rmosolgo on this. |
Wow, didn't expect this one to resurface, thanks!! 😃 Is there a way to suppress the warnings? In my case at least like @benoitongit mentioned, I'm not building an SPA so I'm not as worried about leaks in that way. |
Isn't a Turbolinks front end basically a single-page app? Since Turbolinks replaces the |
To me it's not a SPA, it's an hybrid version to get the responsiveness of a SPA, as they say on turbolinks github:
I don't think you will see the following happen in a SPA:
The root of this issue is Turbolinks caching system. As we've seen, without it, react-rails works perfectly as it is currently. Adding turbolinks cache and then we see the warning. Unsure about the memory leaks with Turbolinks, it would have to be tested to see if it happens or not.. |
After more digging, looks like @rmosolgo you're right. Unmounting is important with Turbolinks to avoid memory leak. |
Looking into this, I think the ideal solution would be to "unbind" the component without touching the markup, thus cleaning up any memory use but preventing the flicker, and complying with the turbolinks cache, but I haven't found a simple way to do this with React or ReactDOM. Maybe we could use ReactDOMServer to render and append the markup again without a mounted component. On the other hand we could add a fallback to attach the listener to 'turbolinks:before-render' if cache is disabled. All this feels like overkill, but it should leave everything in working order |
hmmm - my 2c thinks to look 'the competition' over the shoulder ;) shakacode/react_on_rails@1918345 perhaps that could bring us in the clear? |
I think the best solution is to modify ReactDOM's |
renamed parameter to |
I get an answer about my PR from Dan Abramov. He rightly asked why we get an error about 'another copy of React' in first place. I can not reproduce 'another copy of React' warning by any means. The only way I was able to get this warning is to do a modification in component which leads to an error while rendering component when state was changed wrong way. Can anyone provide me with exact reproducible scenario how to get this warning only in case of |
@szyablitsky it looks like @sevos found out how to fix this problem while adding Turbolinks support for |
They also fixed it like suggested in the ticket on the react-on-rails project shakacode/react_on_rails@1918345 cc @rmosolgo |
@borisrorsvort this change is already reverted back to |
@szyablitsky Thanks for the clarification. Yet the problem persists with |
@borisrorsvort I think you should look at renchap/webpacker-react#14 (comment) and https://sevos.io/2017/02/27/turbolinks-lifecycle-explained.html as @renchap advised. |
It seems that it's more likely mount event issue (not unmount). |
Currently in your gem you listen on
As I explained in my article, this event pairs up nicely only with In case you want to make use of turbolinks' caching, you should listen to this event once, and then listen to render event: document.addEventListener('turbolinks:load', reactOnRailsPageLoaded, {once: true})
document.addEventListener('turbolinks:render', reactOnRailsPageLoaded)
document.addEventListener('turbolinks:before-render', reactOnRailsPageUnloaded) |
|
Alternatively (from comments under my article): document.addEventListener("DOMContentLoaded", reactOnRailsPageLoaded)
document.addEventListener('turbolinks:render', reactOnRailsPageLoaded)
document.addEventListener('turbolinks:before-render', reactOnRailsPageUnloaded) |
@rmosolgo @hrishimittal Do you expect someone to make a pr or are you already working on a fix? |
I tried @sevos solution and, for me, it only changes the warning from:
to
I also noticed that the warnings (both) don't happen when using the Back and Forward arrows (I assume the page is loaded from Turbolinks cache), but they do when clicking on a link (even when the page was visited before, same page I could simply Back into). When the warnings happen, their is a visible "reload" of the page, a previous version of the page loads first, instantaneously followed by a longer load that actually hits the server. I'll try to reproduce the issue in a simpler/smaller app. Update 1First warning reproduced in https://github.com/leonelgalan/turbolinks-react-rails-example/tree/v1, by clicking into the "Two" link, followed by clicking on "One". @sevos fix, removes that first warning, you can see this in https://github.com/leonelgalan/turbolinks-react-rails-example/tree/v2. I haven't been able to reproduce the second warning, my example components are too simple. I'm working on that right now. Update 2I've reproduce the other warning I was getting in https://github.com/leonelgalan/turbolinks-react-rails-example/tree/v3 and I seem to found the cause, a double render of view. See details on the README o https://github.com/leonelgalan/turbolinks-react-rails-example/ Update 3I've learned (or at least I believe I've learned) that this might be caused by Turbolinks rendering a preview from cache and components in there being mounted in that preview.
|
Ah, I have this problem and found this thread. It's closed, but what do I do to fix the problem? Use the Github version of the gem rather than the published version? And what else do I need to do? I see loads of comments about changing Turbolinks caching, but I've no idea what I have to do. My problem is very simple. I've created a Bootstrap tabbed page using React.DOM.etc any time I click on the tabs I get this warning and the tabbed panes don't update. |
the 2.0.2 version on Rubygems includes this fix, so you should try upgrading to that version. If you're still having a problem, could you share your Rails view code for the page with tabs and one of the React components rendered there? |
@rmosolgo I'm getting this error in react-rails 2.2.0. An example is this project: https://github.com/zacharyw/rcg/tree/enchancement/es6 If I load up the conversations index page (the root route by default), everything is fine. If I click into a conversation, that works fine. If I click back to the home page, that's when I see the following error:
After that point it happens any time I click on a conversation or click back to the index page. My components are in In the index view I am rendering the Also, I believe this only started occurring when I upgraded from webpacker gem 1.2 to webpacker 2.0. |
Also happens with me, react-rails (2.4.3). |
I'm seeing this issue with react-rails 2.4.7, and webpacker 3.5. |
Help us help you! Please choose one:
react-rails
, so I've included the stack trace and the exact steps which make it crash.react-rails
with another library, but I'm having trouble. I've described my JavaScript management setup (eg, Sprockets, Webpack...), how I'm trying to use this other library, and why it's not working.This change ecfdc52 has been causing warnings in the console for me. I've followed the standard setup process described in the README. I'm using turbolinks 5 on a new rails 5 app.
When navigating from a page with a react component to one that does not have one and then back I receive the following warning:
I can resolve the error by adding this to my application.js file:
essentially undoing this
The text was updated successfully, but these errors were encountered: