webpacker-react: Components don't re-mount after Turbolinks navigation

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?

About this issue

  • Original URL
  • State: open
  • Created 7 years ago
  • Reactions: 3
  • Comments: 15 (4 by maintainers)

Most upvoted comments

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

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.