I found this bug earlier when I was messing around with the dummy app. To reproduce:
foreman start -f Procfile.staticAt this point, the first page component will still be visible on the page, even though we're at /react_router. When going back the first time, turbolinks unloads and reloads the page. I would expect this navigation event to be handled by react-router. Is this a bug, or expected behavior?
@jtibbertsma This might be impossible to solve. We'd have to ensure that only turbolinks or react-router listens to the back button.
In terms of your example, you can create /spec/dummy-no-turbolinks so your example does not have it.
We are not using turbolinks at https://www.friendsandguests.com/ right now due to this issue.
CC: @alexfedoseev
And see #611 and #612.
I see. I don't think I'll need to create a new dummy app though, since this doesn't break any of my test cases.
I think I can shed some light on this. The way Turbolinks knows that a PopState event is created by itself is by adding a small marker in the history state. That typically looks like this:
> console.log(window.history.state)
{turbolinks: {restorationIdentifier: "9661db46-ae69-494a-9151-9023a5db0aa6"}}
The problem is react-router also uses the history state for the same purpose, and when it's creating a new location it sadly overwrites whatever state that was already in there, so after visiting a page managed by react-router, your history state will look something like this:
> console.log(window.history.state)
{key: 'unbqk4'}
What you want to do is to listen to the 'popstate' events in the browser and to call Turbolinks programmatically whenever the history object doesn't contain the 'turbolinks' property. You can easily do this in your startup file. Here is how I do it:
// client/registration.js
import Turbolinks from 'turbolinks'
Turbolinks.start()
addEventListener('popstate', (o) => {
if (!window.history.state.turbolinks) {
Turbolinks.visit(o.pathname)
}
})
I haven't tested this thoroughly and there may be some edge cases, but in my small test case the back button seemed to work well enough.
PS: If you want to replace history, simply change the action to 'replace':
Turbolinks.visit(o.pathname, {action: 'replace'})
Closing for now.
Hi,
I'm planning to use react on rails and I'm new with react. Does it mean that I have to turn off turbolinks in my app and replace it with react router?
@volkanunsal
What If i want to use react-router inside a certain view e.g. /audits
To get to this view I use Turbolinks.visit() which is fine. but inside this view i'm using react-router for routing. Now lets say i go to another view /account and from there I press back. how do I trigger Turbolinks.visit() from there back to /audits?
The problem is we are migrating slowly from Trubolinks to react-router and we want to be able to jump between the views through the back button.
Most helpful comment
I think I can shed some light on this. The way Turbolinks knows that a PopState event is created by itself is by adding a small marker in the history state. That typically looks like this:
The problem is react-router also uses the history state for the same purpose, and when it's creating a new location it sadly overwrites whatever state that was already in there, so after visiting a page managed by react-router, your history state will look something like this:
What you want to do is to listen to the 'popstate' events in the browser and to call Turbolinks programmatically whenever the history object doesn't contain the 'turbolinks' property. You can easily do this in your startup file. Here is how I do it:
I haven't tested this thoroughly and there may be some edge cases, but in my small test case the back button seemed to work well enough.
PS: If you want to replace history, simply change the action to 'replace':