はじめに
現在Webアプリを開発していますが、学習の都合上、既存のJavaScriptとStimulusの両方を使っていました。しかし、既存JS側で二重登録やチラつきなどの問題が発生したため、Stimulusへ移行することにしました。
問題
- JSの二重登録
- 要素のチラつき
既存JSにロジックを追加しても解決はできますが、コードをリーダブルにするためにStimulusへ移行します。
対策(Stimulus)
- data-controller を使って要素とJSを結びつける
- connect/disconnect で初期化とクリーンアップを分ける
- data-action/data-target で処理を明示的に管理
サンプルコード
フェードイン処理をStimulusへ移行
# ❌NG
document.addEventListener('turbo:load', () => {
const postsContainer = document.querySelector('#posts');
if (!postsContainer) return;
postsContainer.style.opacity = 0;
postsContainer.style.transition = 'opacity 1.5s ease';
requestAnimationFrame(() => {
postsContainer.style.opacity = 1;
});
});
# ✅OK
import { Controller } from '@hotwired/stimulus';
export default class extends Controller {
connect() {
if (document.documentElement.hasAttribute('data-turbo-preview')) return;
this.element.style.opacity = 0;
this.element.style.transition = 'opacity 1.5s ease';
requestAnimationFrame(() => {
this.element.style.opacity = 1;
});
}
disconnect() {
this.element.style.opacity = '';
this.element.style.transition = '';
}
}
# ❌NG
%ul#posts
# ✅OK
%ul#posts{ data: { controller: 'posts-fade', turbo_temporary: true } }
まとめ
- Stimulusを使うとTurbo互換のライフサイクルで自動的に再初期化される
- 多重イベントやチラつきを防げる
- コードも「どの要素に紐づくか」が明確になり、管理しやすい