A great user experience can be created with Rails alone. Tools like UJS remote elements , Stimulus, and Turbolinks are incredibly powerful when combined. Try building your application using these tools before introducing StimulusReflex.
See the Stimulus TodoMVC example application if you are unsure how to do this.
Benefits
StimulusReflex offers 3 primary benefits over the traditional Rails request/response cycle.
All communication happens via web socket - avoids the overhead of traditional HTTP connections
The controller action is invoked directly - skips framework overhead like the middleware chain
DOM diffing is used to update the page - provides faster rendering and less jitter
Here are a few small contrived examples to get you started.
No JavaScript
It's possible to build a reactive application without writing any JavaScript. This requires 2 steps.
Declare the appropriate data attributes in HTML.
Create a server side reflex object with Ruby.
This example will automatically update the page with the latest count whenever the anchor is clicked.
Concerns like managing state and template rendering are handled server side. This technique works regardless of how complex the UI becomes. For example, we could render multiple instances of @count in unrelated sections of the page and they will all update.
Do not create server side reflex methods named reflex as this is a reserved word.
Some JavaScript
Real world applications typically warrant setting up finer grained control. This requires 3 steps.
Declare the appropriate data attributes in HTML.
Create a client side StimulusReflex controller with JavaScript.
Create a server side reflex object with Ruby.
This example will automatically update the page with the latest count whenever the anchor is clicked.
How it Works
Here's what happens whenever a StimulusReflex::Reflex is invoked.
The page that triggered the reflex is re-rerendered.
The re-rendered HTML is sent to the client over the ActionCable socket.
The page is updated via fast DOM diffing courtesy of morphdom.
All instance variables created in the reflex are made available to the Rails controller and view.
The entire body is re-rendered and sent over the socket. Smaller scoped DOM updates may come in a future release.
import { Controller } from 'stimulus';
import StimulusReflex from 'stimulus_reflex';
export default class extends Controller {
connect() {
StimulusReflex.register(this);
}
increment() {
// trigger a server-side reflex and a client-side page update
// pass the step argument with a value of `1` to the reflex method
this.stimulate('ExampleReflex#increment', 1);
}
}
app/reflexes/example_reflex.rb
class ExampleReflex < StimulusReflex::Reflex
def increment(step = 1)
# In a typical Rails app the Rails controller would set the value of @count
# after fetching it from a persistent data store
# @count = @count.to_i + step
# To keep this example simple, we use session to store the value
session[:count] = session[:count].to_i + step
@count = session[:count]
end
end