Skip to content

Instantly share code, notes, and snippets.

@guillaumecabanel
Last active May 2, 2023 07:48
Show Gist options
  • Save guillaumecabanel/fcc979383a89ce0939bdf396d03b678f to your computer and use it in GitHub Desktop.
Save guillaumecabanel/fcc979383a89ce0939bdf396d03b678f to your computer and use it in GitHub Desktop.
Comment gérer la complexité des vues en Rails avec ViewComponent ?

Comment gérer la complexité des vues en Rails avec ViewComponent ?

view_complexity

Une application Web est vite amenée à présenter des vues complexes.

Des éléments asyncrones peuvent être ajoutés à la page.

Des éléments peuvent être ajoutés ou supprimés dynamiquement.

Il faut respecter la cohérence de l'UI. vue-code

Cela peut amener à des vues complexes et difficiles à maintenir.

Même avec l'utilisation de partials et helpers, on a de la logique dans les vues.

ViewComponent

view_component ViewComponent

  • inspiré par les avantages de React

  • développé puis open sourcé par GitHub

  • prototype présenté à la RailsConf 2019

L'objectif principal est de simplifier la manière dont les développeurs construisent des vues complexes pour les applications Rails.

Fonctionnement

Un ViewComponent est objet Ruby et un template.

# app/components/message_component.rb
class MessageComponent < ViewComponent::Base
  def initialize(name:)
    @name = name
  end
end
<%# app/components/message_component.html.erb %>
<h1>Hello, <%= @name %>!</h1>

Une instance qui est passé au #render de Rails.

<%# app/views/demo/index.html.erb %>
<%= render(MessageComponent.new(name: "World")) %>

Qui génère le HTML suivant :

<h1>Hello, World!</h1>

Pourquoi ViewComponent ?

Single Responsibility Principle

Principe de responsabilité unique

Garder la logique dans la vue déroge au SRP et tend à rendre le code complexe.

Don't Repeat Yourself

Ne vous répétez pas

En utilisant des composants réutilisables, on facilite la cohérence de l'UI.

Testabilité & Performance

TL;DR

  • Pour remplacer les partials qui sont réutilisées ou que l'on veut tester facilement.

  • Pour remplacer les templates qui comporte beaucoup de Ruby en ViewComponents.

Bonnes pratiques

Opinion construit sur la base de l'expérience des équipes de GitHub, des articles que j'ai pu lire et de l'expérience chez Kuartz.

Deux types de composants

Génériques

Composants commun pour l'UI

<%= render(ButtonComponent.new) { "Default" } %>
<%= render(ButtonComponent.new(scheme: :primary)) { "Primary" } %>
<%= render(ButtonComponent.new(scheme: :danger)) { "Danger" } %>
<%= render(ButtonComponent.new(scheme: :invisible)) { "Invisible" } %>

buttons

Spécifiques à l'application

Pour transformer un objet métier (souvent un modèle ActiveRecord) en un ensemble de composants génériques.

<%= render(User::ContributorComponent.new(user: @user)) %>

contributor_component

Organisation

"Good frameworks are extracted, not invented." DHH

  1. Composant spécifique à un cas d'utilisation implémenté dans l'application.

  2. Composant adapté pour une utilisation générale dans plusieurs endroits de l'application.

  3. Composant extrait dans une Gem et documenté dans Lookbook.

💡 Tips

  • La plupart des méthodes d'instance peuvent être privées

  • Préférer les ViewComponents aux partials

  • Préférer les ViewComponents aux helpers générant du

  • Éviter le Global state

  • Éviter les requêtes à la base de données

  • Passer un objet plutôt que 3+ attributs d'objet

class MyComponent < ViewComponent::Base
  # bad
  def initialize(repository_name:, repository_owner:, repository_created_at:)
    #...
  end

  # good
  def initialize(repository:)
    #...
  end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment