SolidJS m'a ouvert les yeux

My profile picture

SolidJS a fait de moi un meilleur développeur

En 2015, j'ai découvert React par le biais de Fluxible de Yahoo. Un framework qui se vendait comme "isomorphique". Même si le terme était un peu usurpé, celui-ci était vraiment en avance sur son temps. Fluxible possédait déjà des mécanismes d'hydratation du contenu généré côté serveur ainsi que des actions serveurs. On retrouve d'ailleurs ces mécanismes avec les server-components de React.

Pourquoi je vous parle de Fluxible ?

Les fonctionnalités de Fluxible nous ont permis d'accélérer les développements de nos features à cette époque. Venant d'Angular 1, j'avais la sensation de faire un grand pas en avant dans l'expérience de développement Frontend. Le cycle de vie des composants React me semblait tellement simple comparé aux innombrables comportements imprévisibles d'Angular.
C'est exactement ce que je retrouve dans SolidJS: cette sensation de solutionner certains de mes problèmes récurrents avec React.

C'est quoi SolidJS ?

Une bibliothèque JavaScript déclarative, efficace et flexible pour la création d'interfaces utilisateur. La baseline de SolidJS

SolidJS se démarque de React en ne se basant plus sur un DOM virtuel, il effectue ses opérations directement sur le DOM. Son API plus expressive et plus bas niveau permet un meilleur contrôle sur le rendu des composants. Le moteur de rendu est pensé pour gérer de l'asynchrone en reprenant et améliorant l'API <Suspense />.

import { createSignal, createResource, Suspense } from "solid-js";
import { render } from "solid-js/web";

const fetchUser = async (id: number) =>
  (await fetch(`https://swapi.dev/api/people/${id}/`)).json();

const App = () => {
  const [userId, setUserId] = createSignal<number>();
  const [user] = createResource(userId, fetchUser);

  return (
    <>
      <input
        type="number"
        min="1"
        placeholder="Enter Numeric Id"
        onInput={(e) => setUserId(+e.currentTarget.value)}
      />

      <Suspense fallback={"Loading..."}>
        <div>
          <pre>{JSON.stringify(user(), null, 2)}</pre>
        </div>
      </Suspense>
    </>
  );
};

render(App, document.getElementById("app"));
Solid permet d'utiliser directement des Promesses dans ses composants. Il suffit d'entourer les composants dans une bordure Suspense pour continuer le rendu de l'interface.

SolidJS n'hésite pas à bouleverser mes habitudes

Et c'est une bonne chose. Plus j'utilisais React, plus je me confortais dans ses bizarreries:

Ces comportements, je les avais intégrés à ma façon de développer. J'en étais conscient, j'en palliais certains via des librairies. J'ai maintenant conscience que React souhaite brute force la réactivité via un rendu presque systématique de l'interface. Après tout, c'était la promesse lors de son introduction par Facebook : ne pas manquer de mise à jour de l'interface.

La réactivité "Fine-Grained"

Le paradigme change avec SolidJS, les composants sont des constructeurs tel l'ancienne syntaxe avec des classes dans les premières versions de React. L'idée étant de profiter du pattern des signaux pour mettre à jour des noeuds du DOM directement à leur valeur où à la dérivé de leur valeur.

Une fois le composant initialisé, il est censé être capable d'écouter les changements d'états de vos signaux. Pour cela, il faut penser à utiliser les directives JSX comme <Show> ou <For> pour les tableaux.

L'interface de SolidJS reste relativement proche de celle de React, ce qui facilite la transition. Un useState devient un createSignal qui retourne un accesseur à la place de la valeur. Ce changement tout simple permet notamment de s'affranchir de la memoisation des fonctions de rappels, ou des tableaux de dépendances.

Tout en SolidJS alors ?

Je serais vraiment plein de désillusion si je vendais SolidJS comme la solution. Celui-ci possède également son lot de pièges dans lequel je suis tombé.

export default function Greeting(props) {
  const { greeting, name, ...others } = props;

  return <h3 {...others}>{greeting} {name}</h3>
}
Ici si greeting/name sont des signaux, vous allez perdre la réactivité...

Afin de comprendre pourquoi j'ai loupé un render, j'ai dû comprendre ce qu'était un signal, ou comment le moteur de rendu allait mettre à jour le DOM. J'ai dû également faire un parallèle avec ma compréhension du fonctionnement de React et saisir les avantages des signaux.

Cette guerre des Frameworks me semble saine : de nombreux échanges de tweets ou encore d'articles de blog ont permis d'expliquer et de vulgariser les mécanismes de nos Frameworks. J'ai pris beaucoup de plaisir à lire les articles de Ryan ainsi que les podcasts vidéos avec des invités de choix sur de nombreux sujets.

J'ai hâte de voir vers quoi le futur du développement Frontend va tendre.