Giter Site home page Giter Site logo

Comments (10)

florentdestremau avatar florentdestremau commented on June 29, 2024 10

I find the decision not to fire the turbo:load event not in line with the docs:

Turbo Drive evaluates <script> elements in a page’s each time it renders the page. You can use inline body scripts to set up per-page JavaScript state or bootstrap client-side models. To install behavior, or to perform more complex operations when the page changes, avoid script elements and use the turbo:load event instead.

So that means that if my form has some JS in it (ex. booting a bootstrap-datepicker with jquery, launching a google autocomplete...), the JS is not re-initialized but the the DOM has changed.

I ended up using turbo:render instead to boot my custom JS (I'm migrating my current app to turbo, so a lot of custom JS hanging around). I don't see why the docs would point me to turbo:load then if turbo:render is the more universal event ? Am I missing something ?

from turbo.

rossinkiwi avatar rossinkiwi commented on June 29, 2024 9

Does this mean that all of our existing legacy code that once was based on:
$(document).ready( function( e ) { ... code to init legacy js like parsley, datatables, datetimepicker etc. ...}
Then replaced with:
$(document).on('turbolinks:load', function( e ) { ... legacy js code ...}
Then replaced with:
$(document).on('turbo:load', function( e ) { ... legacy js code ...}
Actually needs to be replaced with:
$(document).on('turbo:render', function( e ) { ... legacy js code ...}
to handle the case of a form submission that has validation errors?

But the Stimulus Handbook indicates that this might get triggered twice:

turbo:render fires after Turbo renders the page. This event fires twice during an application visit to a cached location: once after rendering the cached version, and again after rendering the fresh version.

Which could be problematic because some of that legacy js gets torn down on turbo:before-cache which wont get called between the two turbo:render events.

It would be great if there were a bit more backward compatibility with turbolinks...

from turbo.

sstephenson avatar sstephenson commented on June 29, 2024 6

You shouldn't listen for the turbo:load event unless you specifically want to know that a visit—a navigation that changes the URL—has finished.

The Hotwire way is to put the code you want to run in the connect() method of a Stimulus controller, and then add a matching data-controller attribute to an element so that the code runs whenever the element appears on the page.

from turbo.

SimoTod avatar SimoTod commented on June 29, 2024 4

@sstephenson Silly question, the page does get replaced though (it re-renders the old page triggering a turbo:render event).
If the goal is to keep the page as it is, why does it replace the content? Thanks

from turbo.

florentdestremau avatar florentdestremau commented on June 29, 2024 4

I ended up booting 3 times: turbo:render, turbo:load and load.

Because React seems to be idempotent, and our codebase seems to be as well, we haven't noticed a major memory leak or slowness. Still, this is upsetting because it's not advertised as such.

What I understand is that only stimulus code is automatically re-booted if necessary, but external dependencies are to be either idempotent and booted multiple times, or booted once and hope for no re-render @sstephenson ?

from turbo.

james-em avatar james-em commented on June 29, 2024 2

One year later, do we have a proper workaround for this? Is turbo really encouraging us to use an event that is fired twice?

Thanks!

Solution: #520 (comment)

from turbo.

sstephenson avatar sstephenson commented on June 29, 2024

This is by design. The turbo:load event fires in response to a successful visit, and form submissions only trigger visits when the server responds with a redirect.

from turbo.

nyrf avatar nyrf commented on June 29, 2024

So, the PR #39 is useless? We often use turbo:load event to run some codes, if this is by design, after submit form fail and return 422, the code inside turbo:load won't run. So, how to run the codes inside turbo:load? Thanks.

from turbo.

nyrf avatar nyrf commented on June 29, 2024

The Hotwire way is to put the code you want to run in the connect() method of a Stimulus controller, and then add a matching data-controller attribute to an element so that the code runs whenever the element appears on the page.

I see, thanks.

from turbo.

buncis avatar buncis commented on June 29, 2024

I also have a react component that I attached using turbo:load
my current solution is

adding document listerner for turbo:load and turbo:render

  document.addEventListener('turbo:load', () => {
    let domContainer = document.querySelector('#like_button_container');
    if (domContainer) {
      ReactDOM.render(<MyComponent />, domContainer);
    }
  })
  
  document.addEventListener('turbo:render', () => {
    let domContainer = document.querySelector('#like_button_container');
    if (domContainer) {
      ReactDOM.render(<MyComponent />, domContainer);
    }
  })

What I understand is that only stimulus code is automatically re-booted if necessary, but external dependencies are to be either idempotent and booted multiple times, or booted once and hope for no re-render

if that's so
how about we attached the react component using stimulus controller?
I hope this solutions bring me no problemo in the futuro

import React from 'react'
import ReactDOM from 'react-dom'

const MyComponent = () => (
 <h2>React ❤️ Stimulus</h2>
)

import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
 static targets = [ "react" ]

 connect() {
   if (this.hasReactTarget){
     ReactDOM.render(<MyComponent />, this.hasReactTarget);
   }
 }
}

from turbo.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.