C'est BIEN mieux que NextJS (TanStack Server Components)

BBetter Stack
컴퓨터/소프트웨어AI/미래기술

Transcript

00:00:00React server components. Pour ou contre ?
00:00:04Ça semble être surtout contre ces temps-ci, mais ça
00:00:08pourrait bien changer avec l'arrivée de TanStack dans la partie.
00:00:13C'est exact, nous avons maintenant des TanStack
00:00:21server components, et ils ont adopté une approche très différente de Next.js.
00:00:26Jetons un œil.
00:00:31Je vais commencer par un paragraphe de leur article d'annonce,
00:00:35qui, je pense, rassurera beaucoup de monde.
00:00:40Il dit : "La plupart des gens conçoivent les React server components
00:00:45d'une manière centrée sur le serveur.
00:00:48Le serveur possède l'arborescence, "useClient" marque les parties interactives,
00:00:52et les conventions du framework déterminent comment tout cela s'assemble.
00:00:57Cela transforme les React server components,
00:01:01d'une primitive utile, en un élément autour duquel toute votre application doit graviter.
00:01:06Nous ne pensons pas que vous devriez devoir adhérer
00:01:10à tout ce modèle dès le départ simplement pour tirer profit des React server components."
00:01:15En substance, ce qu'ils disent, c'est qu'ils ne veulent pas suivre la voie de Next.js
00:01:18où tout est "server component" par défaut, et où vous avez besoin de la directive "useClient"
00:01:22là où vous voulez de l'interactivité.
00:01:27Au lieu de cela, TanStack veut penser les choses ainsi : et si vous pouviez utiliser
00:01:32des React server components de manière aussi granulaire que vous pourriez récupérer du JSON côté client ?
00:01:36Avec cet objectif en tête, examinons
00:01:40la manière dont ils ont réellement implémenté les server components,
00:01:45car, spoiler : j'adore vraiment leur approche.
00:01:49Ce que j'ai ici, c'est une application TanStack Start normale,
00:01:53donc tout, pour le moment, va être un composant client.
00:01:58La seule chose que j'ai faite, ce sont quelques petites étapes d'installation nécessaires
00:02:01pour faire fonctionner les server components, ce qui consiste essentiellement à installer quelques paquets
00:02:06et à modifier votre config Vite.
00:02:10Voici à quoi ressemble la page actuellement ; nous avons notre composant de salutation ici
00:02:14qui, comme vous pouvez le voir, est actuellement un composant client,
00:02:18et dans le code, il s'agit littéralement d'un simple composant React.
00:02:23Ensuite, en bas, nous avons une route TanStack normale, et nous utilisons le composant de salutation.
00:02:27Maintenant, disons que dans notre composant de salutation, vous vouliez effectuer une certaine logique sur le serveur.
00:02:32Dans mon cas, je veux récupérer le nom d'hôte du système d'exploitation,
00:02:36puis aussi certaines variables d'environnement qui ne sont disponibles que sur le serveur,
00:02:41juste pour vous montrer que cela s'exécute réellement là-bas.
00:02:46Pour l'instant, si j'essaie d'utiliser "os.hostname",
00:02:51cela ne fonctionnera pas car c'est une fonction Node, et elle n'est pas disponible dans le navigateur.
00:02:55Ce que nous devons faire, alors, c'est prendre notre composant de salutation et le rendre sur le serveur.
00:02:59La première étape pour faire cela dans TanStack Start est une simple fonction serveur.
00:03:03Comme vous pouvez le voir, j'en ai une ici appelée "getGreeting",
00:03:07et tout ce que nous faisons à l'intérieur, c'est utiliser la nouvelle fonction "renderServerComponent",
00:03:12en plaçant notre composant à l'intérieur, et en retournant le server component rendable
00:03:16que nous obtenons en retour.
00:03:21Vous pouvez voir cela comme une simple création d'une requête GET pour notre composant.
00:03:25Ensuite, tout ce que nous devons faire est simplement de récupérer le composant depuis la fonction serveur que nous avons créée,
00:03:30et nous pouvons le faire à l'intérieur d'un "loader" sur une route ici,
00:03:34donc nous attendons simplement "getGreeting",
00:03:38puis nous retournons cela également, et c'est toujours un server component rendable.
00:03:43Ensuite, nous pouvons l'utiliser à l'intérieur de
00:03:47notre route ici en utilisant "useLoaderData",
00:03:52et nous utilisons simplement le composant en bas comme ceci.
00:03:56Avec cela, nous avons maintenant notre premier TanStack server component.
00:04:01Vous pouvez voir que "os.hostname" fonctionne maintenant, et il récupère également
00:04:05des variables d'environnement qui ne sont disponibles que sur le serveur.
00:04:10Maintenant, ce que j'adore absolument à propos de cette implémentation,
00:04:14c'est que si vous remarquez, la seule nouvelle chose ici est la fonction "renderServerComponent".
00:04:18Le reste était juste du TanStack Start normal.
00:04:22Vous pourriez remplacer cela par de simples données JSON retournées, et vous les récupéreriez exactement de la même manière.
00:04:28Je pense aussi que cette implémentation est vraiment explicite
00:04:32quant à l'endroit où votre code s'exécute réellement.
00:04:37Vous faites tout à l'intérieur d'une fonction serveur, donc c'est assez clair que cela va être exécuté sur le serveur,
00:04:42et aussi à l'intérieur du "renderServerComponent".
00:04:47En fait, je pense que je peux améliorer mon code de démonstration ici en prenant simplement
00:04:51les fonctions que nous exécutons ici en haut, que je veux exécuter sur le serveur, en les mettant
00:04:56à l'intérieur de la fonction serveur,
00:05:00puis en passant simplement ces valeurs dans mon composant de salutation en tant que "props",
00:05:05donc maintenant mon composant de salutation est essentiellement juste un composant nu qui peut être utilisé
00:05:09sur le client ou sur le serveur.
00:05:14J'exécute toute la logique que je veux exécuter sur le serveur à l'intérieur de ma fonction serveur ici.
00:05:18Encore une fois, il est assez explicite que cela va être exécuté sur le serveur.
00:05:22Cela ressemble littéralement à l'exact opposé de la logique utilisée dans Next.js,
00:05:27et je l'adore.
00:05:31Cela signifie que je peux penser à React de manière normale : tout est client d'abord,
00:05:36puis j'ajoute des server components par-dessus quand je le souhaite.
00:05:41Mais que faire si je voulais utiliser un composant client à l'intérieur de mon server component,
00:05:45donc imbriqué dans l'arborescence ?
00:05:49Disons que je voulais ajouter un bouton de compteur ici
00:05:53qui, chaque fois qu'on clique dessus, augmente le compteur.
00:05:57Eh bien, si j'essaie simplement d'ajouter cela dans mon server component ici avec
00:06:01un "onClick" puis aussi un appel à "useState",
00:06:05vous pouvez voir que ça casse complètement.
00:06:10Il dit que "useState" n'est pas une fonction ou que sa valeur de retour n'est pas itérable,
00:06:14et c'est parce que "Greeting" est utilisé comme un server component.
00:06:18Nous ne pouvons pas utiliser cette fonctionnalité client.
00:06:23Pour corriger cela, vous avez deux options, et la deuxième option est certainement la meilleure à utiliser,
00:06:27mais la première option sera familière à ceux d'entre vous qui ont utilisé Next.js.
00:06:32Nous pouvons simplement déplacer cette logique dans son propre composant, puis utiliser la directive "useClient".
00:06:36Cela fonctionne dans les server components de TanStack Start ; nous pouvons simplement utiliser
00:06:40le composant à l'intérieur du server component maintenant, et comme vous pouvez le voir, tout fonctionne bien.
00:06:44L'inconvénient de cette approche, cependant, est que nous avons maintenant un server component
00:06:48contrôlant le rendu d'un composant client,
00:06:53et cela peut commencer à devenir un peu désordonné,
00:06:58c'est-à-dire que si je voulais savoir où se trouvait mon composant de compteur dans l'arborescence,
00:07:03j'irais sur ma route ici et je verrais que nous avons un server component "Greeting",
00:07:08puis je reviendrais dans le server component "Greeting",
00:07:12et à l'intérieur du server component, je verrais que nous avons un composant client,
00:07:17et ce désordre peut vraiment commencer à s'accumuler, et rendre la frontière
00:07:22entre serveur et client un peu floue.
00:07:27TanStack ne se contenterait pas de cela, cependant.
00:07:32Ils se sont demandé : et si le serveur n'avait pas besoin de décider de chaque partie de l'interface
00:07:37qui est destinée au client ?
00:07:42Et cela les a conduits à créer quelque chose d'entièrement nouveau : les composants composites.
00:07:46Pour en utiliser un, la première chose que je vais faire, c'est supprimer notre composant client de notre server component,
00:07:50et je vais simplement le remplacer
00:07:56par n'importe quels enfants de notre composant "Greeting".
00:07:59Ensuite, nous devons aussi changer ce que nous retournons de
00:08:04notre fonction serveur ici.
00:08:08Au lieu de retourner un server component rendable, nous devons retourner
00:08:12ce qu'on appelle une "composite source".
00:08:16Pour ce faire, nous pouvons utiliser notre deuxième fonction d'aide de TanStack server components :
00:08:20"createCompositeComponent".
00:08:24Ici, nous construisons essentiellement un composant
00:08:28où les "props" ici sont considérées comme les emplacements (slots).
00:08:32J'utilise juste un emplacement enfant très simple,
00:08:36donc tout ce que nous mettrons en tant qu'enfant de mon composant composite sera passé
00:08:41dans ce "props.children", que
00:08:45je transmets au composant "Greeting" que nous avions juste avant.
00:08:49Avec cela, encore une fois, ce que nous devons faire, c'est
00:08:53simplement récupérer notre composant composite depuis notre fonction serveur,
00:08:57et nous faisons cela exactement de la même manière dans
00:09:01le "loader" ici.
00:09:06Vous voyez, je renomme simplement "source" en "Greeting",
00:09:10puis je le charge avec "useLoaderData".
00:09:15La seule différence ici, cependant, c'est que nous ne pouvons pas utiliser cela comme un composant.
00:09:19Vous voyez, il génère une erreur ici.
00:09:23Pour rendre réellement un composant composite, nous devons utiliser le composant d'aide
00:09:28"CompositeComponent" que nous obtenons depuis TanStack server components,
00:09:33et en tant que "source prop", nous passons
00:09:38le composant composite que nous récupérons de notre fonction serveur que nous avons créée plus tôt.
00:09:42Avec cela, mon server component est maintenant en train de se rendre comme nous l'avions avant,
00:09:47et je transmets aussi le compteur en tant qu'enfants de ce composant composite,
00:09:51et cela est passé au "Greeting" là où nous
00:09:56l'avions configuré ici, donc il le transmet dans "props.children",
00:10:01donc tout fonctionne maintenant
00:10:05parfaitement bien.
00:10:10Je peux aussi aller dans mon composant compteur et supprimer la directive que nous avions ici,
00:10:14puisqu'elle n'est plus nécessaire car il sait que ce sera un composant client
00:10:18puisqu'il est à l'intérieur d'un composant composite.
00:10:22Ceci est utilisé comme un emplacement.
00:10:26Maintenant, il peut sembler que nous ayons obtenu exactement le même résultat,
00:10:31mais avec plus de travail que juste utiliser la directive "useClient",
00:10:36mais la puissance vient vraiment de l'expérience développeur, et c'est un peu un changement par rapport au modèle "useClient".
00:10:40Au lieu d'avoir notre serveur qui décide où nos composants clients se rendent,
00:10:44comme quand nous avions le composant compteur à l'intérieur du server component lui-même,
00:10:49ce que nous faisons avec les composants composites, c'est dire : "Hé,
00:10:53il va y avoir un emplacement ici, nous allons rendre un composant client,
00:10:58mais le server component lui-même n'a aucune idée de ce que cela va être."
00:11:03Nous ajoutons cela plus tard dans notre code client,
00:11:07donc nous gérons tous les composants basés sur le client à l'intérieur du code client lui-même.
00:11:12Ce n'est que le début, aussi.
00:11:16Si nous jetons un œil à une page plus complexe comme celle-ci, sur les posts, où ce post est rendu côté serveur,
00:11:21il y a deux problèmes que je veux résoudre.
00:11:25Le premier est que je veux ajouter des actions comme
00:11:31aimer le post et suivre l'auteur, mais je veux les ajouter au-dessus du titre ici,
00:11:36et je veux utiliser un composant client.
00:11:41Pour le moment, j'utilise simplement ce modèle d'emplacement "children",
00:11:45ce qui signifie que si je
00:11:49ajoutais mes actions de post ici en bas, elles iraient juste là où sont les commentaires,
00:11:54puisque c'est comme ça que nous avons
00:11:59le composant configuré, donc je veux un moyen de dire à mon server component où mettre des composants clients spécifiques.

Key Takeaway

TanStack Start propose une alternative aux React Server Components via les composants composites, permettant une intégration granulaire et explicite de la logique serveur sans contraindre toute l'architecture de l'application.

Highlights

TanStack Start adopte une approche où l'application est client-first, contrairement au modèle Next.js qui impose les React Server Components par défaut.

La fonction renderServerComponent permet d'exécuter du code côté serveur, comme os.hostname, au sein d'une route TanStack standard.

Les composants composites de TanStack permettent d'insérer des composants clients dans une arborescence serveur sans créer de dépendances floues entre les deux environnements.

Le modèle des composants composites évite l'utilisation de la directive 'useClient' au sein des composants serveurs, clarifiant ainsi la frontière entre le code client et serveur.

Le chargement des composants serveurs s'effectue via des loaders standards, ce qui garantit une cohérence avec le flux de données JSON habituel de TanStack.

Timeline

Philosophie et approche TanStack

  • TanStack rejette le modèle Next.js où l'application doit graviter autour des Server Components.
  • L'objectif est d'utiliser les Server Components de manière granulaire, similaire à une requête JSON côté client.

L'approche TanStack cherche à éviter la rigidité de Next.js où la directive 'useClient' devient nécessaire partout pour gérer l'interactivité. Le framework privilégie une structure où le développeur choisit quand et où activer le rendu serveur au lieu de subir une configuration par défaut imposée.

Implémentation des Server Components

  • L'installation nécessite quelques paquets et une modification de la configuration Vite.
  • La fonction renderServerComponent permet de transformer un composant standard en composant serveur exécutable côté Node.
  • Le résultat d'un composant serveur se récupère via le loader de route, similaire à un fetch de données JSON classique.

Le processus commence par la définition d'une fonction serveur utilisant renderServerComponent pour encapsuler le composant. Ce composant est ensuite retourné par un loader de route TanStack Start, puis rendu via useLoaderData. Cette méthode explicite garantit que l'exécution se déroule uniquement sur le serveur.

Composants composites et gestion client-serveur

  • L'imbrication directe d'un composant client utilisant useState dans un composant serveur provoque une erreur.
  • La directive 'useClient' est une option de correction, mais elle complexifie l'arborescence et brouille les frontières.
  • createCompositeComponent permet de définir des emplacements (slots) où les composants clients peuvent être insérés sans que le composant serveur ne connaisse leur nature.

Les composants composites résolvent le problème de l'imbrication client-serveur en séparant la définition de l'emplacement du rendu effectif du composant. Le serveur définit un espace réservé, et le code client décide plus tard quel composant y insérer. Cela élimine la nécessité de directives 'useClient' au sein de l'arborescence serveur, simplifiant la maintenance du code.

Community Posts

No posts yet. Be the first to write about this video!

Write about this video