クイックリファレンス

StimulusReflex チートシート

Ruby on RailsにおけるStimulusReflexクイックリファレンス:リフレックスアクション、morphモード、ライフサイクルコールバック、クライアントイベント。

· 公開日

コアコンセプト

StimulusReflexは、WebSockets(ActionCable)とCableReadyを利用してRailsアプリケーション上でリアクティブなリアルタイムUIを実現します。

基本的なReflex

<!-- view.html.erb -->
<button data-reflex="click->Counter#increment">Increment</button>
# app/reflexes/counter_reflex.rb
class CounterReflex < ApplicationReflex
  def increment
    @count = element.dataset[:count].to_i + 1
  end
end

Morphモード

Page Morph(デフォルト)

コントローラアクションを介してページ全体を再レンダリングし、差分のみをDOMに適用します。

Selector Morph

# app/reflexes/example_reflex.rb
class ExampleReflex < ApplicationReflex
  def update_metric
    morph "#metric-display", render(partial: "metrics/metric", locals: { value: 42 })
  end
end

Nothing Morph

クライアントのDOMを更新せずにサーバーサイドのロジックのみを実行します。

class ExampleReflex < ApplicationReflex
  def background_task
    LongRunningJob.perform_later
    morph :nothing
  end
end

ライフサイクルメソッド

サーバーサイドコールバック

class ExampleReflex < ApplicationReflex
  before_reflex :authenticate
  around_reflex :measure_time
  after_reflex :log_activity
end

クライアントサイド共通コールバック

  • beforeReflex(element, reflex, noop, reflexId): WebSocketリクエスト送信前
  • reflexSuccess(element, reflex, noop, reflexId): Reflex実行およびDOM更新完了後
  • reflexError(element, reflex, error, reflexId): サーバーが未補足のエラーを発生させた場合
  • reflexHalted(element, reflex, noop, reflexId): Reflexが throw :abort で中断された場合
  • afterReflex(element, reflex, noop, reflexId): 成功・失敗にかかわらず常に実行
  • finalizeReflex(element, reflex, noop, reflexId): 最終クリーンアップフック

DOMイベント

  • stimulus-reflex:before
  • stimulus-reflex:success
  • stimulus-reflex:error
  • stimulus-reflex:halted
  • stimulus-reflex:after
  • stimulus-reflex:connected
  • stimulus-reflex:disconnected
  • stimulus-reflex:ready

実践パターン

フォーム処理

フォーム要素内外で発火したReflexは、自動的にフォーム入力をシリアライズして params へ渡します。

Promiseチェーン

this.stimulate('Comments#create')
  .then(() => this.showSuccess())
  .catch((err) => this.handleError(err))

永続要素 (Permanent Elements)

data-reflex-permanent を指定した要素は、ページ全体のMorph処理時にも再描画されず保護されます。

<div data-reflex-permanent>
  <video id="player" src="video.mp4" controls></video>
</div>

参考資料

関連テーマ