Zustand zwischen Astro-Inseln teilen
Wenn du eine Astro-Website mit Insel-Architektur / Partieller Hydratation aufbaust, bist du vielleicht schon auf dieses Problem gestoßen: Ich möchte den Zustand zwischen meinen Komponenten teilen.
UI-Frameworks wie React oder Vue nutzen “Kontext”-Anbieter, die von anderen Komponenten konsumiert werden können. Bei der partiellen Hydratation von Komponenten in Astro oder Markdown kannst du diese Kontext-Wrapper jedoch nicht verwenden.
Astro empfiehlt eine andere Lösung für die gemeinsame Speicherung auf der Client-Seite: Nano Stores.
Warum Nano Stores?
Abschnitt betitelt Warum Nano Stores?Die Nano Stores Bibliothek ermöglicht es dir, Stores zu erstellen, mit denen jede Komponente interagieren kann. Wir empfehlen Nano Stores aus folgenden Gründen:
- Sie sind leichtgewichtig. Nano Stores liefern das Minimum an JS, das du brauchst (weniger als 1 KB), ohne jegliche Abhängigkeiten.
- Sie sind Framework-agnostisch. Das bedeutet, dass die gemeinsame Nutzung von Zuständen zwischen Frameworks nahtlos ist! Astro ist auf Flexibilität ausgelegt, daher lieben wir Lösungen, die unabhängig von deiner Präferenz eine ähnliche Entwicklererfahrung bieten.
Dennoch gibt es eine Reihe von Alternativen, die du ausprobieren kannst. Dazu gehören:
- Svelte’s eingebaute Stores
- Solid signals außerhalb eines Komponentenkontextes
- Vue’s Reaktivitäts-API
- Senden von benutzerdefinierten Browser-Ereignissen zwischen Komponenten
🙋 Kann ich Nano Stores in .astro
-Dateien oder anderen serverseitigen Komponenten verwenden?
Nano Stores können in serverseitigen Komponenten importiert, beschrieben und gelesen werden, aber wir empfehlen es nicht! Das liegt an einigen Einschränkungen:
- Das Schreiben in einen Store aus einer
.astro
-Datei oder einer nicht-hydratisierten Komponente hat keine Auswirkung auf den Wert, der von Client-seitigen Komponenten (EN) empfangen wird. - Du kannst einen Nano Store nicht als “prop” an clientseitige Komponenten übergeben.
- Du kannst keine Änderungen aus einer
Astro
-Datei abonnieren, da Astro-Komponenten nicht neu gerendert werden.
Wenn du diese Einschränkungen verstehst und trotzdem einen Anwendungsfall findest, kannst du Nano Stores ausprobieren! Denke daran, dass Nano Stores speziell für die Reaktivität auf Änderungen auf dem Client konzipiert sind.
🙋 Wie unterscheiden sich die Svelte Stores von den Nano Stores?
Nano Stores und Svelte Stores sind sich sehr ähnlich! Tatsächlich kannst du in Nanostores die gleiche $
-Verknüpfung für Subscriptions verwenden, die du auch in Svelte Stores benutzen kannst.
Wenn du Bibliotheken von Drittanbietern vermeiden willst, sind Svelte Stores ein großartiges Werkzeug für die inselübergreifende Kommunikation. Dennoch könntest du Nano Stores bevorzugen, wenn dir a) die Add-ons für “objects” und async state gefallen oder b) du zwischen Svelte und anderen UI-Frameworks wie Preact oder Vue kommunizieren möchtest.
🙋 Wie unterscheiden sich Solid Signals von Nano Stores?
Wenn du schon eine Weile mit Solid arbeitest, hast du vielleicht schon versucht, signals oder stores außerhalb deiner Komponenten zu verschieben. Dies ist eine großartige Möglichkeit, den Zustand zwischen Solid-Inseln zu teilen! Versuche, Signals aus einer gemeinsamen Datei zu exportieren:
…und alle Komponenten, die sharedCount
importieren, teilen sich denselben Zustand. Obwohl dies gut funktioniert, könntest du Nano Stores bevorzugen, wenn du a) die Add-ons für “objects” und async state magst, oder b) zwischen Solid und anderen UI-Frameworks wie Preact oder Vue kommunizieren möchtest.
Nano Stores installieren
Abschnitt betitelt Nano Stores installierenUm loszulegen, installiere Nano Stores zusammen mit dem Hilfspaket für dein bevorzugtes UI-Framework:
Hier gibt es kein Hilfspaket! Nano Stores können wie normale Svelte Stores verwendet werden.
Du kannst die Nano-Stores-Anleitung von hier aus aufrufen oder unserem Beispiel unten folgen!
Anwendungsbeispiel - E-Commerce Warenkorb-Flyout
Abschnitt betitelt Anwendungsbeispiel - E-Commerce Warenkorb-FlyoutNehmen wir an, wir bauen eine einfache E-Commerce-Oberfläche mit drei interaktiven Elementen:
- Ein “In den Warenkorb”-Formular
- Ein Warenkorb-Flyout, um die hinzugefügten Artikel anzuzeigen
- Ein Flyout-Knopf für den Einkaufswagen
Teste das fertige Beispiel auf deinem Rechner oder online über Stackblitz.
Deine Basis-Astro-Datei könnte so aussehen:
“Atoms” verwenden
Abschnitt betitelt “Atoms” verwendenBeginnen wir damit, dass wir unser CartFlyout
öffnen, wenn CartFlyoutToggle
angeklickt wird.
Erstelle zunächst eine neue JS- oder TS-Datei, die unseren Store enthält. Wir verwenden dafür ein “Atom”:
Jetzt können wir diesen Store in jede Datei importieren, die lesen oder schreiben muss. Wir beginnen damit, unser CartFlyoutToggle
zu verknüpfen:
Dann können wir isCartOpen
von unserer CartFlyout
-Komponente lesen:
“Maps” verwenden
Abschnitt betitelt “Maps” verwendenMaps sind eine gute Wahl für Objekte, in die du regelmäßig schreibst! Neben den standardmäßigen get()
- und set()
-Hilfen, die ein atom
bietet, hast du auch eine .setKey()
-Funktion, um einzelne Objektschlüssel effizient zu aktualisieren.
Jetzt wollen wir den Überblick über die Artikel in deinem Warenkorb behalten. Um Duplikate zu vermeiden und den Überblick über die “Menge” zu behalten, können wir deinen Warenkorb als Objekt mit der ID des Artikels als Schlüssel speichern. Wir verwenden dafür eine Map.
Jetzt fügen wir einen cartItem
-Store zu unserer cartStore.js
von vorhin hinzu. Du kannst auch zu einer TypeScript-Datei wechseln, um die Form zu definieren, wenn du das möchtest.
Jetzt exportieren wir einen addCartItem
-Helper (Hilfsfunktion), den unsere Komponenten verwenden können.
- Wenn dieser Artikel nicht in deinem Warenkorb ist, füge den Artikel mit einer Startmenge von 1 hinzu.
- Wenn es diesen Artikel doch schon gibt, erhöhe die Menge um 1.
🙋 Warum wird hier .get()
anstelle eines useStore
-Helpers verwendet?
Du hast vielleicht bemerkt, dass wir hier cartItems.get()
aufrufen, anstatt den useStore
-Helper aus unseren React / Preact / Solid / Vue-Beispielen zu verwenden. Das liegt daran, dass useStore dafür gedacht ist, die Komponenten neu zu rendern. Mit anderen Worten, useStore
sollte immer dann verwendet werden, wenn der Wert des Shops auf der Benutzeroberfläche dargestellt wird. Da wir den Wert auslesen, wenn ein Ereignis ausgelöst wird (in diesem Fall AddToCart
), und wir nicht versuchen, den Wert zu rendern, brauchen wir useStore
hier nicht.
Wenn unser Shop eingerichtet ist, können wir diese Funktion in unserem AddToCartForm
aufrufen, sobald das Formular abgeschickt wird. Außerdem öffnen wir das Warenkorb-Flyout, damit du eine vollständige Warenkorbübersicht siehst.
Zum Schluss stellen wir die Artikel im Warenkorb in unserem CartFlyout
dar:
Jetzt solltest du ein vollständig interaktives E-Commerce-Beispiel mit dem kleinsten JS-Bündel der Galaxis haben 🚀
Probiere das fertige Beispiel auf deinem Rechner oder online über Stackblitz aus!
Recipes