How to get Turbolinks to play well with ReactJS?

In my app I’m using react-phoenix and turbolinks via phoenix_turbolinks. Both libs are working, but after navigating around the react components disappear and no longer render. I know this has to do with how Turbolinks replaces the body of the page, but I’m not sure how to solve the issue.

Any ideas? Here’s my app.js file.

import "phoenix_html"

import Turbolinks from 'turbolinks';

import "react-phoenix"
import MediaEditor from "./components/media_editor"

window.Components = {
  Media,
  MediaEditor
}

// A hack because the logout form doesn't submit when contained in a
// ul.dropdown. This may be an issue with Bootstrap or Phoenix.HTML
// 
const submitParentForm = () => {
	let logoutButton = document.querySelector('[data-submit="parent"]');
	if (logoutButton) {
    	logoutButton.addEventListener('click', () => {
    	    logoutButton.parentNode.submit();
	    })
	}
}

document.addEventListener("turbolinks:load", () => {
	submitParentForm()
})

Turbolinks.start();

I’m not sure there is a really good way to mix turbolinks and react, they do the same thing but in different ways. No doubt you could get them to work with lots of hooks and other things, but if you are using react then you should just dynamically load the content that way anyway I’d think. :-\

Take a peak at: https://github.com/nerdyworm/returb/blob/master/web/static/js/app/react.js#L107

When the page is loaded via turbolinks you will need to find all the components and remount them in the dom.

I believe this is a fairly straightforward block of js… however, if you have any questions please don’t hesitate to ask.

Cheers,
Benjamin

3 Likes

Interesting, though isn’t it unmounting and remounting everything on every turbolinks update? Is there no way to refine it to only what changes? I know Unpoly.js (similar to turbolinks but more features) has callbacks to do precisely that.

If a full teardown/rebuild becomes an issue turbolinks has the concept of a persistent element. This will copy the element into the new page so you can skip the rebuild cycle. It will require some additional work to make that happen though.

There are certainly optimizations that can be made, but for the few things I’ve used this technique with I haven’t needed them.

Cheers,
Benjamin

1 Like

I tend to agree in general. In this case I need React for a single component that has a rich UI and lives on a single page. Otherwise, I wouldn’t bother. I think the easiest way might be to disable tubolinks for that specific link.

1 Like

Thanks. I’ll try to use this as a guide and let you know how I get on. It might be worth to avoid the complexity and disable the link for that particular page, though.