Comment gérer l’état dans les applications Astro



Lors de la conception d’une application avec le framework Astro, une question fréquente concerne la gestion de l’état de l’application et son partage entre les divers composants et frameworks. Nano Stores se présente comme une solution de premier choix pour la gestion d’état dans Astro, grâce à sa compatibilité avec React, Preact, Svelte, Solid, Lit, Angular et même Vanilla JS.

Découvrez comment gérer efficacement l’état au sein d’un projet Astro. Ce guide vous accompagnera pas à pas dans la création d’une application de prise de notes simple, utilisant Nano Stores pour la gestion de l’état et permettant le partage de celui-ci entre des composants React et Solid.js.

Qu’est-ce qu’Astro ?

Le framework Astro vous offre la possibilité de bâtir des applications web en vous appuyant sur des frameworks d’interface utilisateur reconnus tels que React, Preact, Vue ou Svelte. Il s’articule autour d’une architecture basée sur des composants, où chaque page Astro est constituée d’un assemblage de différents composants.

Dans un souci d’optimisation du temps de chargement des pages, Astro privilégie une utilisation minimale de JavaScript côté client et effectue le prérendu des pages sur le serveur.

Astro a été conçu pour être l’outil idéal pour la publication de sites web axés sur le contenu. On peut penser par exemple aux blogs, aux pages de destination, aux sites d’actualités et autres pages où le contenu prédomine sur l’interactivité. Pour les composants que vous définissez comme interactifs, le framework se chargera de fournir uniquement le code JavaScript minimal nécessaire pour activer cette interactivité.

Installation et configuration

Si vous disposez déjà d’un projet Astro opérationnel, vous pouvez passer cette section.

Cependant, si vous n’avez pas encore de projet Astro, il sera nécessaire d’en créer un. La seule condition préalable est d’avoir Node.js installé sur votre environnement de développement local.

Pour initier un nouveau projet Astro, ouvrez votre invite de commande, naviguez vers le répertoire où vous souhaitez créer votre projet, et exécutez la commande suivante :

npm create astro@latest

Confirmez l’installation d’Astro en tapant « y » et donnez un nom au dossier de votre projet. En cas de difficultés, n’hésitez pas à consulter le tutoriel de configuration officiel d’Astro.

Une fois le projet créé, ajoutez React en exécutant la commande suivante :

npx astro add react

Enfin, installez Nano Stores pour React avec la commande ci-dessous :

npm i nanostores @nanostores/react

Toujours dans votre terminal, placez-vous dans le dossier racine de votre projet et lancez l’application avec l’une des commandes suivantes (selon votre gestionnaire de packages) :

npm run dev

Ou :

yarn run dev

Ou :

pnpm run dev

Accédez à http://localhost:3000 dans votre navigateur pour visualiser un aperçu de votre site web.

Une fois votre projet Astro configuré, l’étape suivante consiste à établir un espace de stockage pour les données de l’application.

Création du magasin de notes

Créez un fichier nommé noteStore.js dans le répertoire /src à la racine de votre application. Dans ce fichier, utilisez la fonction atom() de nanostores pour créer un espace de stockage pour les notes :

import { atom } from "nanostores"

export const notes = atom([])

export function addNote(note) { notes.set([...notes.get(), note]) console.log("Added note: ", note.get()) }

La fonction addNote() prend une note en paramètre et l’enregistre dans le magasin de notes. L’utilisation de l’opérateur de propagation lors de l’enregistrement de la note permet d’éviter toute mutation des données. L’opérateur de propagation est une méthode JavaScript rapide pour copier des objets.

Création de l’interface utilisateur de l’application de prise de notes

L’interface utilisateur se composera simplement d’un champ de saisie pour enregistrer la note et d’un bouton qui, une fois activé, ajoutera la note au magasin.

Dans le répertoire src/components, créez un nouveau fichier nommé NoteAddButton.jsx. Ensuite, insérez le code suivant dans le fichier :

import {useState} from "react"

import {addNote, notes} from "../noteStore"

export default function NoteAdder() { const [userNote, setUserNote] = useState('')

return( <> <label htmlFor="note">Add a note: </label>

<input type="text" name="note" id="note" onChange={(event) => setUserNote(event.target.value)} /> <button onClick={() => addNote(userNote)}>Add</button> <ul> { $notes.map((note, index) => { <li key={index}>{note}</li> }) } </ul> </> ) }

Ce code ajoute la note à l’état du composant au fur et à mesure de la saisie. Puis, lorsque vous cliquez sur le bouton, la note est sauvegardée dans le magasin. Il récupère également les notes depuis le magasin et les affiche dans une liste non ordonnée. Grâce à cette méthode, la note apparaît immédiatement sur la page une fois le bouton Enregistrer activé.

Maintenant, dans votre fichier pages/index.astro, importez NoteAddButton et utilisez-le dans les balises <main> :

import NoteAddButton from "../components/NoteAddButton.jsx"

---

<Layout title="Welcome to Astro."> <main> <NoteAddButton client:load /> </main> </Layout>

Si vous retournez maintenant dans votre navigateur, vous verrez l’élément de saisie et le bouton affichés sur la page. Saisissez du texte dans le champ et cliquez sur le bouton Enregistrer. La note apparaît instantanément sur la page et persiste même après l’actualisation de votre navigateur.

Partage d’état entre deux frameworks

Supposons que vous souhaitiez partager l’état entre React et Solid.js. La première étape consiste à ajouter Solid à votre projet avec la commande suivante :

npx astro add solid

Ensuite, ajoutez les Nano Stores pour solid.js en exécutant :

npm i nanostores @nanostores/solid

Pour créer l’interface utilisateur avec solid.js, rendez-vous dans le répertoire src/components et créez un nouveau fichier nommé Notes.js. Ouvrez ce fichier et créez le composant Notes à l’intérieur :

import {useStore} from "@nanostores/solid"

import {notes} from "../noteStore"

import {For} from "solid-js"

export default function Notes() { const $notes = useStore(notes)

return( <> <h1>My notes</h1> <ul> <For each={notes()} /> {(note) => <li>{note}</li>} </For> </ul> </> ) }

Dans ce fichier, vous importez les notes depuis le magasin, vous parcourez chaque note et vous les affichez sur la page.

Pour afficher le composant Note créé ci-dessus avec Solid.js, il suffit d’aller dans votre fichier pages/index.astro, d’importer NoteAddButton et de l’utiliser dans les balises <main> :

import NoteAddButton from "../components/NoteAddButton.jsx"

import Notes from "../components/Notes.jsx"

---

<Layout title="Welcome to Astro."> <main> <NoteAddButton client:load /> <Notes client:load /> </main> </Layout>

Retournez dans votre navigateur, saisissez du texte dans le champ et cliquez sur le bouton Enregistrer. La note apparaîtra sur la page et persistera également entre les différents rendus.

Autres nouvelles fonctionnalités d’Astro

Grâce à ces techniques, vous êtes en mesure de gérer l’état de votre application Astro et de le partager entre les composants et les frameworks. Mais Astro offre bien d’autres fonctionnalités pratiques, comme la collecte de données, la minification HTML et le rendu parallélisé.