-
Notifications
You must be signed in to change notification settings - Fork 443
Description
I have a question or may be a misconception about the life cycle of Stimulus controllers.
Let's say I have a simple controller that toggles a <body> class and stores that state in localStorage:
// foobar_controller.js
import { Controller } from '@hotwired/stimulus'
export default class extends Controller {
toggle() {
document.body.classList.toggle('foobar');
localStorage.setItem('foobar', document.body.classList.contains('foobar'));
}
}…
<head>
<script src="app.js" async></script>
</head>
<body>
…
<button type="button" data-controller="foobar" data-action="foobar#toggle">Toggle Class</button>
…
</body>Now I also want to restore that body class state which is saved in localStorage. My initial though was to put that into the initialize() method:
import { Controller } from '@hotwired/stimulus'
export default class extends Controller {
initialize() {
if ('true' === localStorage.getItem('foobar')) {
document.body.classList.add('foobar');
}
}
…
}My expectation was that (once app.js is loaded and cached by the browser) this would be immediately executed as soon as the node the controller is registered on is started to be processed by the browser.
However, in actuality it kind of looks like all Stimulus controllers are only initialized once the whole page finished loading - i.e. it almost looks like everything is only processed on DOMContentLoaded. I assumed that stimulus controllers would be initialized as soon as possible via Mutation observers. Thus in this case the body class is added too late for my use case.
Or another example would be the click action for a menu button - the event listener only seems to be added once the whole DOM was loaded, meaning that on a large page the menu button (which is at the very top of the page typically) does nothing for quite some time.
Was my expectation wrong? Or is there something wrong with my setup. In my case I use webpack - together with hotwired/stimulus-webpack-helpers. The app.js looks like this for example:
import { Application } from '@hotwired/stimulus'
import { definitionsFromContext } from '@hotwired/stimulus-webpack-helpers'
import './css/app.scss';
// Start Stimulus application
const application = Application.start()
const context = require.context('./controllers', true, /\.js$/)
application.load(definitionsFromContext(context));
application.debug = process.env.NODE_ENV === 'development';