Breaking news: an alternative to React
By: Edgardo Martin Gerez
Tags: React, Software Development, Components, Programming

Recently I was reading some articles, in order to stay ahead of the latest trends within the ecosystem of my favorite framework Ruby on Rails, and I came across an article that read: “There is absolutely no technical needs for RoR devs to use ReactJS “. Clearly it was something that caught my attention, and I had a question that helped me to dig deeper into the subject: Why go against a library as popular as React?

In order to better understand how this can be possible, we should decompose the final solution into different portions that synergistically work to improve development productivity (something common in Rails) and simplify the development team, and process, removing diversity from it.

The elements of this recipe are the following, some of these will be covered in this article, and others we will leave for another opportunity:

Ruby on Rails

If we have to do a brief review of what is Ruby on Rails (RoR for simplicity), it is a framework written in Ruby, an object-oriented programming language, with a very simple and readable syntax, it is used by technology companies such as Github, Gitlab, Airbnb, Shopify, among others.

Since it has many first-rate technology companies, which base their products on this technology, many of them contribute to the growth, improvement and generation of new ideas within the Rails ecosystem.

ViewComponent

This is a frontend framework that allows us to decompose views into components, thinking of them as blocks that contain only the necessary information and to which certain behavior can be added according to the information they receive.

We can think of the components as an evolution of the Decorator Pattern, since in the end, it fulfills a similar but enriched function.

The components are Ruby objects, with a well-defined interface with which we have the certainty of the input and output information, allowing us to improve the unit tests on them, as we will see later in their benefits.

Stimulus

This Javascript microframework emerged from Basecamp (the company from which RoR emerged), comes to replace other libraries such as JQuery, or Vanilla Javascript, allowing us to define controllers that add behavior to our HTML.

StimulusReflex

Library that allows us to extend the functionalities of both RoR and Stimulus. The ultimate purpose of this library is to intercept interactions with the application by the user and send them in real time (over Websockets) to be handled by Rails.

It is responsible for managing the state of the application and the changes applied to the interfaces, achieving update rates of between 20–30 ms.

CableReady

Gem that allows the creation of applications to generate real-time experiences for users. It uses sockets provided by ActionCable, a framework present in RoR.

Now, all these new components at first glance can be scary, especially when they seem to introduce unnecessary complexity, but the truth is that many of them work with a minimum amount of effort in configuration and code, for example between StimulusReflex + CableReady. In other cases, they are libraries that replace others, such as ViewComponent, which replaces the use of Partials.

Benefits of removing front-end frameworks

At this point, I want to highlight the main benefits that we identify and adhere to with respect to avoiding introducing a frontend framework or library (React, Angular, Vue, etc).

Use the same RESTFul application that we have, we don’t need to define endpoints or anything extra.

The rendering is kept on the server side, allowing to use ERB, Slim, HAML, etc.

Keeping the rendering on the server side, no longer implies reloading the entire page when a change is made, rather with the help of these technologies, we only change the parts of the view that are needed, thus improving the general performance and the usability.

The development team remains less diversified in technologies, allowing to maintain a solid background in it.

Progressive inclusion, which removes a “Yes or No” panorama, since all these technologies can be incorporated little by little, replacing and refactoring existing code perhaps?

Centralization of business logic

In this first iteration about new trends and the development of modern applications with RoR, we are going to delve a little more about ViewComponents, leaving the other components for another time.

What is a component and why is it important?

In its most simplistic form, a component is a Ruby object that returns HTML. The main benefits that we obtain from using them are:

Reuse: Allowing us to take advantage of the components defined in different situations throughout the project. Testing: Acceptance or integration tests are already solved in Rails, through the SystemTests or IntegrationTests, but these must run the entire server, load base information and execute the entire life cycle, something expensive both in the time it takes its execution, like its writing. Through the use of components, we can perform unit tests on them, being these simpler to write and faster to execute their tests. Performance: In point 1 I talked about the re-use that allows us to carry out the components, this was already solved to a certain extent with the use of Partials, but the components give us superior performance, according to the benchmarks made by the developers up to 10x compared to the original Partials.

What does a component look like?

If we refer to the initial documentation of the framework provided by the Github team, we can find all the details about how exactly it works, how to install, the generators it provides.

What we should know is that now, our original views inside the app/views/ * directory will make use of the render method and the instances of our components that we have defined will show the output.

These components will be contained within the app/components/* directory and each of them has two files, which must be named the same, a file with an .rb extension and a file with an .html.erb extension (or any rendering engine that we use, eg: HAML, SLIM, etc.).

app/views/posts/new.html.slim

= render PostForm::Component.new(post: @post)

As we saw before, in this way what we do is render the component instance, with a parameter, which in this case is a new instance of the Post class

app/components/post_form/component.rb

module PostForm

class Component < ViewComponent::Base

def initialize(post:)

@post = post

end private attr_reader :post

end

end

This would be our definition of the class that we are instantiating in our view. Here we could define certain methods that give behavior to the component according to the information we pass. Similar to what we can do using a decorator pattern.

app/components/post_form/component.html.slim

= simple_form_for sale do |f|

= f.input :title

= f.input :body = f.button :submit, class: 'btn btn-sm btn-primary float-right'

And finally, we have our component with an HTML extension, which will finally be what our returns to be shown in the view.

References

https://stimulusjs.org/

https://rubyonrails.org/

https://docs.stimulusreflex.com/

https://cableready.stimulusreflex.com/

viewcomponent.org

https://medium.com/@obie/react-is-dead-long-live-reactive-rails-long-live-stimulusreflex-and-viewcomponent-cd061e2b0fe2