ui.render Ereignis jedes Mal aus, wenn es eine Render-Site zeichnen möchte, und Ihr Hook für dieses Ereignis gibt zurück, was dort gezeichnet werden soll.
Diese Karte zeigt, wo ein Mod in einer Terminal-Sitzung zeichnen kann:
Um eine Eigenschaft oder ein Limit nachzuschlagen, siehe die Referenz.
Erstellen Sie ein Pane mit Registerkarten
In diesem Abschnitt erstellen Sie einen Mod, der einen/hello-tabs Befehl hinzufügt, und der Befehl öffnet ein Pane. Ein Pane ist eine Seitenleiste neben dem Transkript in einem breiten Vollbildterminal oder eine gerahmte Region über der Eingabeaufforderung. Dieses Pane zeigt zwei Registerkarten, und die zweite Registerkarte hat eine Schaltfläche, die eins zu einem Zähler addiert. Die Anzahl ist immer noch da, nachdem Sie Claude Code neu starten.
Der fertige Mod sieht so aus. Die Aufzeichnung öffnet das Pane, wechselt zur zweiten Registerkarte, drückt die Schaltfläche ein paar Mal und kehrt zur ersten Registerkarte zurück:
1
Erstellen Sie das Plugin
Ein Mod ist ein Plugin mit einem Manifest, einer Benennen Sie Ihren Einstiegspunkt in
hooks.json, die auf Ihren Code verweist, und der Codedatei. Erstellen Sie einen Mod erklärt jeden. Erstellen Sie ein Verzeichnis namens hello-tabs mit .claude-plugin und hooks Verzeichnissen darin, speichern Sie dann die ersten zwei Dateien.Speichern Sie das Manifest als hello-tabs/.claude-plugin/plugin.json:hello-tabs/.claude-plugin/plugin.json
hello-tabs/hooks/hooks.json:hello-tabs/hooks/hooks.json
2
Schreiben Sie den Code
Der Code führt drei Aufgaben aus, eine in jedem Hook:Jeder Hook führt auch etwas aus, das der Code nicht deutlich macht:
- Fügt den
/hello-tabsBefehl hinzu - Öffnet das Pane, wenn Sie diesen Befehl ausführen
- Zeichnet den Inhalt des Pane: die Reihe von Registerkarten und den Hauptteil der offenen Registerkarte
tab und count, halten den Status des Pane.Speichern Sie dies als hello-tabs/hooks/register.js:hello-tabs/hooks/register.js
session.startliest auch die gespeicherte Anzahl aus$.store, einem Schlüssel-Wert-Speicher, der zwischen Sitzungen bestehen bleibt.command.runteilt Claude Code nur mit, dass das Pane existiert. Das Öffnen eines Pane zeichnet nichts von selbst: Claude Code löst dannui.renderaus, um zu fragen, was darin geht.ui.rendergibt den Element-Baum zurück, einBox, das andere Boxen, Text und Schaltflächen enthält, und erstellt ihn jedes Mal austabundcountneu.
onPress Callback aus, der eine Variable ändert und redraw aufruft. Claude Code führt dann den ui.render Hook erneut aus, und der Hook erstellt einen neuen Baum aus den neuen Werten. Jede interaktive Zeichnung verwendet diesen Render-Zyklus: Ein Callback ändert den Status, und der Hook zeichnet aus dem neuen Status neu.3
Öffnen Sie das Pane
Starten Sie Claude Code in Ihrer Shell mit
claude --plugin-dir ./hello-tabs. Führen Sie an der Claude Code Eingabeaufforderung /hello-tabs aus. Ein Pane öffnet sich mit 1: One und 2: Two oben. Drücken Sie 2, dann drücken Sie a, die Hotkey für Add one, ein paar Mal. Die Anzahl steigt.4
Überprüfen Sie, dass die Anzahl gespeichert wurde
Drücken Sie Esc, um das Pane zu schließen, und beenden Sie dann die Sitzung. Starten Sie Claude Code in Ihrer Shell erneut mit dem gleichen
claude --plugin-dir ./hello-tabs Befehl, und führen Sie an der Claude Code Eingabeaufforderung /hello-tabs aus. Die Anzahl ist dort, wo Sie sie gelassen haben.Um die Anzahl zu löschen, lassen Sie den Mod $.store.delete('count') aufrufen. Behalten Sie den Status behandelt, wie lange jede Art von Wert dauert.Wählen Sie, wo Sie zeichnen möchten
Einui.render Hook läuft für jede Render-Site, es sei denn, Sie grenzen ihn auf die gewünschte ein. Um die Render-Site auszuwählen, übergeben Sie einen Filter, genannt Matcher, als zweites Argument an on. { component: 'Pane' } führt den Hook nur für Panes aus. Im Hook benennt e.component die Site, e.surface sagt, welche App zeichnet, und e.props enthält die eigenen Daten der Site. Für ein Pane ist e.requestId die id, mit der Sie es geöffnet haben.
Zwei Sites sind leer, bis ein Mod sie ausfüllt, das Pane und das Band. Wählen Sie eine Registerkarte, um zu sehen, was jede ist und wie man darin zeichnet:
- Pane
- Band über der Eingabeaufforderung
Ein Pane ist eine Seitenleiste neben dem Transkript in einem breiten Vollbildterminal oder eine gerahmte Region über der Eingabeaufforderung. Mit mehreren offenen Panes erhält jedes eine Registerkarte, die seinen Titel anzeigt.Ein Pane erscheint, wenn Ihr Mod
$.ui.open mit einer id aufruft, die Sie wählen, wie in $.ui.open({ id: 'hello-tabs' }). Öffnen Sie ein Pane zum richtigen Zeitpunkt behandelt die anderen Felder und wann ein Pane auf ein breiteres Terminal wartet.Um in Ihrem Pane zu zeichnen, filtern Sie auf { component: 'Pane' } und überprüfen Sie, dass e.requestId Ihre id ist.Ändern Sie, was Claude Code bereits zeichnet
Claude Code zeichnet den Großteil seiner Benutzeroberfläche selbst: Nachrichten, Tool-Call-Zeilen, den Spinner und mehr. Jeder dieser Teile ist auch eine Render-Site, daher kann ein Mod ihn umgestalten oder ersetzen. Um einen zu ändern, filtern Sie Ihrenui.render Hook auf seinen Namen aus dieser Tabelle:
An einer Site, die Claude Code bereits zeichnet, hat Ihr Hook drei Möglichkeiten: ein Detail ändern, die Zeichnung ersetzen oder sie allein lassen. Wählen Sie eine Registerkarte, um jede auf den Spinner angewendet zu sehen. Die Beispiele lesen eine
calls Variable, die ein anderer Hook zählt, wie im Tutorial-Mod.
- Ändern Sie ein Detail
- Ersetzen Sie die Zeichnung
- Lassen Sie es allein
Um Claude Codes Zeichnung zu behalten und einen Teil davon zu ändern, übergeben Sie Der Spinner behält seine Animation und sein Wort, und Ihr Text folgt dem Wort:
next eine Kopie des Ereignisses mit geänderten props. Dieser Hook ändert den Text nach dem Wort des Spinners:AskUserQuestion, ist einer, daher kann ein Mod diesen ändern.
Das Terminal und die Desktop-App lösen nicht alle gleichen Sites aus. Pane, AbovePrompt, Spinner und die Transkript-Sites funktionieren in beiden. Ein paar andere Statuszeilen werden nur im Terminal ausgelöst. Die Render-Sites-Tabelle listet auf, wo jede ausgelöst wird.
Öffnen Sie ein Pane zum richtigen Zeitpunkt
Ein Pane erscheint nur, wenn Ihr Mod es öffnet. Wie und wann Sie es öffnen, entscheidet, ob es den Tastaturfokus erhält, wie viel Platz es anfordert und ob es überhaupt in einem schmalen Terminal angezeigt wird. Um ein Pane zu öffnen, rufen Sie$.ui.open mit einer id auf, die Sie wählen. Die id ist der Name des Pane: Ihr ui.render Hook überprüft sie, und Sie übergeben sie erneut, um das Pane zu schließen.
$.ui.close mit der id auf, mit der Sie es geöffnet haben:
id nimmt $.ui.open diese optionalen Felder:
Um einem Befehl zu ermöglichen, das Pane zu öffnen, während Claude arbeitet, fügen Sie
immediate: true hinzu, wenn Sie den Befehl registrieren. Ohne ihn wartet ein Befehl, der während eines Turns eingegeben wird, bis der Turn endet.
Wenn ein Pane auf ein breiteres Terminal wartet
Ein Pane, das Ihr Mod öffnet, ohne gefragt zu werden, erscheint nicht in einem schmalen Terminal, daher kann es einen kleinen Bildschirm nicht übernehmen. Ob es erscheint, hängt davon ab, was es geöffnet hat:- Geöffnet durch etwas, das der Benutzer getan hat, z. B. ein Befehl, den er ausgeführt hat, oder eine Schaltfläche, die er gedrückt hat, das Pane erscheint bei jeder Breite
- Geöffnet durch Ihren Mod, der von selbst handelt, z. B. von einem Timer oder einem
turn.startHook, das Pane erscheint nur in einem Terminal mit mindestens 144 Spalten Breite. Nachdem der Benutzer dieses Pane einmal selbst geöffnet hat, reichen 110 Spalten aus.
$.ui.open zu { isPlaced: true } aufgelöst. Wenn das Pane wartet, ist isPlaced false und reason ist ein String, der sagt, warum. Ein wartendes Pane erscheint, wenn der Benutzer es öffnet oder das Terminal verbreitert. Um zu sagen, dass etwas verfügbar ist, ohne ein Pane zu öffnen, rufen Sie $.ui.toast('Your message') auf, das eine kleine Mitteilung zeigt, die nach ein paar Sekunden verschwindet.
Erstellen Sie einen Baum aus Elementen
Was einui.render Hook zurückgibt, ist ein Element-Baum: eine Beschreibung dessen, was zu zeichnen ist, bestehend aus Boxen, Text und Steuerelementen, die ineinander verschachtelt sind. Sie beschreiben die Zeichnung, und Claude Code rendert sie im Terminal oder der Desktop-App.
Um die Elemente zu erhalten, rufen Sie $.ui.resolve(e) in Ihrem Hook auf, wie in const { Box, Text, Button } = $.ui.resolve(e). Jedes Element ist eine Funktion. Sie übergeben ihr Props, und Sie setzen die Elemente und Strings, die darin gehen, in children.
Die meisten Zeichnungen verwenden vier Elemente. Wählen Sie eine Registerkarte, um jedes zu sehen und wie das Terminal es zeichnet:
- Text
- Box
- Input
Text zeichnet einen String mit optionalem Styling wie bold und color:
Wenn Ihr Modul eine
.tsx oder .jsx Datei ist, können Sie den Baum als JSX schreiben. Destrukturieren Sie die Elemente zuerst aus $.ui.resolve(e), da ein Hooks-Modul keine Element-Globals hat.
Wenn ein Baum ein Element verwendet, das die App nicht hat, ein Prop, das ein Element nicht nimmt, oder ein Kind, wo keines geht, zeichnet Claude Code seine eigene Version der Site.
In einer Sitzung, die mit --plugin-dir gestartet wurde, sagt eine Transkriptzeile so, wie ui.render (Pane) refused: Text prop "bogusProp" is not allowed; the engine drew its own. Das Debug-Protokoll zeichnet es als ui.render (Pane): a hook returned a tree that does not validate mit dem gleichen Grund auf. Nichts anderes erscheint in der Sitzung, also wenn eine Zeichnung nicht angezeigt wird, überprüfen Sie diese Zeile oder das Protokoll.
Zeichnen Sie ein Gitter von farbigen Zellen
Für eine Wärmekarte, eine Sparkline oder ein Spielbrett im Terminal zeichnen Sie einRaster und nicht ein Box für jede Zelle. Ein Raster nimmt einen key, seine Größe in columns und rows und cells, die jede Zelle in einen String packt. Jede Zelle sind drei Zahlen: der Code-Punkt des Zeichens, seine Farbe und seine Hintergrundfarbe. Eine Farbe ist eine Hexadezimalzahl mit zwei Ziffern jeweils für Rot, Grün und Blau, wie 0xc62828 für ein Rot oder 0x01000000 für das Standard des Terminals.
Die Desktop-App hat kein Raster, also überprüfen Sie e.surface und zeichnen Sie dort Text. Dieser Pane-Hauptteil zeichnet eine drei mal zwei Wärmekarte:
rows Array ist der Teil, den Sie ändern würden, und cellsOf verwandelt es in den gepackten String. Der Hook zeichnet nur in einem Pane, dessen id heat ist, also öffnen Sie eines mit $.ui.open({ id: 'heat' }) von einem Befehl, wie das hello-tabs Beispiel sein Pane öffnet.
Jedes Zeichen muss eine Zelle breit sein. Um ein Raster, das bereits auf dem Bildschirm ist, zu animieren, rufen Sie $.ui.blit mit der id des Pane als requestId, dem key des Raster, der gleichen Größe und neuen Zellen auf. Für dieses Beispiel ist das $.ui.blit({ requestId: 'heat', key: 'grid', columns: 3, rows: 2, cells: cellsOf(newRows) }). Es malt dieses eine Element neu, ohne Ihren ui.render Hook erneut auszuführen.
Reagieren Sie auf Drücke und Eingaben
Wenn der Benutzer eine Schaltfläche drückt, in ein Feld tippt oder aus einer Liste auswählt, die Ihr Mod gezeichnet hat, ruft Claude Code die Funktion auf, die Sie diesem Steuerelement gegeben haben, und sie läuft in Ihrem Modul. Jedes Steuerelement nimmt seine eigenen Callbacks:Button: nimmtonPress(e), wobeie.surfacedie App ist, von der der Druck kamInput: nimmtonSubmit(value)undonInput(value)Select: nimmtonSelect(value)mit seinen Auswahlmöglichkeiten inoptions, eine Liste von mindestens einer Auswahlmöglichkeit mit eindeutigen Werten, wie[{ value: 'sm', label: 'Small' }, { value: 'lg', label: 'Large' }]
key, also geben Sie jedem einen. Jede Verwendung eines Steuerelements löst auch ui.press, ui.input oder ui.select mit dem key in e.element aus, und ein anderer Mod kann diese Ereignisse hooken. Sein Hook läuft vor Ihrem Callback, daher sieht er, was der Benutzer in Ihren Input tippt und kann es ändern oder an Stelle Ihres Callbacks antworten. Die Mods API hat keine Methode, die die Schaltfläche eines anderen Mods drückt.
Tastaturfokus und Hotkeys
Ihr Mod liest die Tastatur nie selbst. Der Benutzer drückt eine Taste, Claude Code entscheidet, welches Ihrer Steuerelemente es ist, und der Callback dieses Steuerelements läuft. Abgesehen von einer Ziffern-Hotkey auf dem Band passiert das nur, während Ihr Pane oder Band den Tastaturfokus hat. Der Rest der Zeit gehen Tasten zur Eingabeaufforderung.Wie ein Pane den Tastaturfokus erhält
Ein Pane erhält den Tastaturfokus auf eine von drei Arten:- Ihr Mod öffnet es mit
focus: truevon einem Befehl oder einem Druck - Der Benutzer drückt Ctrl+X dann Tab
- Der Benutzer klickt darauf
focus: true nur, während die Eingabeaufforderung leer ist und nichts anderes den Tastaturfokus hat. Ein Pane, das sich öffnet, während der Benutzer tippt, nimmt seine Tastenanschläge nicht.
Was jede Taste tut
Diese Tabelle listet auf, was eine Taste tut, während Ihr Pane oder Band den Tastaturfokus hat:
Ein Mod kann Tab oder die Pfeiltasten nicht an etwas anderes binden, daher steuert ein Spiel mit
w, a, s und d.
Setzen Sie eine Hotkey und den ersten Fokus
Zwei Props auf einem Steuerelement entscheiden, wie die Tastatur es erreicht:hotkey: um dem Benutzer zu ermöglichen, eineButtonmit einer Taste zu drücken, geben Sie ihr einehotkeyvon einer Ziffer oder einem Kleinbuchstaben, wie inhotkey: 'a'autoFocus: um zu wählen, welches Steuerelement den Fokus hat, wenn das Pane sich öffnet, fügen SieautoFocus: truehinzu. Lassen Sie das Prop bei den anderen weg, da Claude CodeautoFocus: falseablehnt.
Im Terminal benennen Sie die Taste im Label einer geklammerten Schaltfläche oder verwenden Sie
plain: true, damit der Benutzer sehen kann, was zu drücken ist. Die Elements-Referenz hat die anderen Button Regeln: action, Ziffern-Hotkeys auf dem Band und zwei Schaltflächen auf einer Hotkey.
Nehmen Sie eingegebenen Text und zeichnen Sie eine Reihe für jedes Element
Viele Panes sind ein Textfeld mit einer Liste darunter. Das Beispiel in diesem Abschnitt ist ein Notizen-Pane: Sie tippen eine Notiz und drücken Enter, um sie hinzuzufügen, und jede Notiz hat einex Schaltfläche, die sie löscht. Mit zwei hinzugefügten Notizen zeichnet das Terminal das Pane so:
- Nehmen Sie eingegebenen Text: ein
InputruftonSubmit(value)mit dem Text des Feldes auf, wenn der Benutzer Enter drückt, undonInput(value)bei jeder Änderung - Zeichnen Sie eine Liste: ordnen Sie Ihre Daten einer Reihe jeweils zu, und geben Sie jedem
keyder Reihe seine eigene
- Fügen Sie eine Notiz hinzu: tippen Sie eine Zeile und drücken Sie Enter. Die Zeile erscheint als neue Reihe, und das Feld leert sich.
- Löschen Sie eine Notiz: drücken Sie Tab, bis die
xSchaltfläche der Notiz den Fokus hat, dann drücken Sie Enter. Dasxist das Label der Schaltfläche und keine Hotkey, daher drückt das Tippen des Buchstabens es nicht.
hello-tabs: Der Callback ändert notes, ruft redraw auf und speichert die Liste in $.store.
Das Feld leert sich nach jedem Submit wegen seines value Props. value ist der Text, den das Feld hält, wenn es gezeichnet wird, und das Tippen des Benutzers ersetzt ihn, bis Ihr Hook das Feld erneut zeichnet. Das Beispiel zeichnet das Feld immer mit ''.
Das Beispiel speichert die Notizen und lädt sie nicht. Um sie in der nächsten Sitzung zurückzubringen, lesen Sie sie in einem session.start Hook, wie hello-tabs count liest.
Drei Props machen die Zeile des Feldes aus, Note: Type a note and press Enter ⏎ add:
Das Absenden eines
Input startet keinen Turn, es sei denn, Ihr Callback ruft $.prompt.submit auf.
Zeichnen Sie eine Site neu
Eine Zeichnung ist ein Schnappschuss: Sie zeigt, was Ihrui.render Hook das letzte Mal zurückgegeben hat, als der Hook lief. Um etwas Neues zu zeigen, muss der Hook erneut laufen. Claude Code führt ihn für einige Änderungen erneut aus, und Ihr Mod fragt nach dem Rest.
Wenn Claude Code ohne Aufforderung neu zeichnet
Claude Code führt Ihrenui.render Hook erneut aus, wenn sich die Props der Site ändern oder die Breite des Terminals ändert. Es führt den Hook nicht auf einem Timer aus, und es kann nicht sagen, wenn sich eine Variable in Ihrem Modul ändert.
Zeichnen Sie neu, wenn sich Ihre Daten ändern
Um Ihre Sites nach Ihren eigenen Datenänderungen erneut zu zeichnen, rufen Sie$.ui.invalidate('ui.render') auf. Dieses Pane zählt Drücke. Der Callback der Schaltfläche ändert count und fragt dann nach einem Neuzeichnen:
hello-tabs Beispiel wickelt den gleichen Aufruf in seine redraw Funktion.
Ein Wert, den Sie in $.state halten, braucht den Aufruf nicht, da das Schreiben des Wertes die Sites neu zeichnet, die ihn lesen.
Zeichnen Sie auf einem Timer neu
Um eine Uhr, einen Countdown oder einen Wert von außerhalb der Sitzung aktuell zu halten, zeichnen Sie nach einem Zeitplan neu. Starten Sie einen Timer imsession.start Hook des Moduls. Wenn das Modul bereits einen hat, wie hello-tabs, fügen Sie die $.clock.every Zeile hinzu:
ui.render Hook einmal pro Sekunde aus. Der Timer stoppt, wenn das Modul neu geladen wird, und die neue Kopie des Moduls startet ihren eigenen.
Wie oft eine Site neu gezeichnet werden kann
Claude Code begrenzt, wie oft es neu zeichnet, daher kann Ihr Mod$.ui.invalidate so oft aufrufen, wie sich seine Daten ändern. Das sichtbare Pane und das Band haben ein höheres Limit als andere Sites, und die Limits-Tabelle hat die Zahlen.
Aufrufe, die schneller als das Limit kommen, werden in einem Neuzeichnen kombiniert. Dieses Neuzeichnen führt Ihren Hook einmal aus, und der Hook liest Ihre Daten, wie sie in diesem Moment sind, daher zeigt der neueste Wert und die Werte dazwischen nicht. Eine Animation kann nicht schneller als das Limit laufen.
Behalten Sie den Status
Ein Mod hat drei Orte, um einen Wert zu halten, und sie unterscheiden sich darin, wie lange der Wert dauert: bis das Modul neu geladen wird, bis die Sitzung endet oder von einer Sitzung zur nächsten. Wählen Sie danach, wie lange der Wert dauern muss:$.store.get(key) wird zu dem Wert oder undefined aufgelöst, und $.store.set(key, value) nimmt jeden JSON-Wert.
Behalten Sie einen Wert in $.state
$.state hält Werte für die Länge einer Sitzung, und es zeichnet für Sie neu. Es ist reaktiver Status: ein ui.render Hook, der einen Wert liest, abonniert ihn, daher zeichnet Claude Code diese Site jedes Mal neu, wenn Sie den Wert schreiben, und Sie rufen $.ui.invalidate nicht auf. Ein Wert in $.state überlebt auch ein Reload des Moduls, das eine Variable nicht tut.
Um es einzurichten, deklarieren Sie Ihre Werte, zeigen Sie Ihr Manifest auf die Deklaration, dann definieren und verwenden Sie jeden Wert. Die Beispiele verschieben den count aus hello-tabs in $.state.
Deklarieren Sie die Werte
Deklarieren Sie die Werte in einer Typendatei. Der äußere Schlüssel ist der Name Ihres Plugins, und jeder Eintrag darunter ist ein Wert und sein Typ. Speichern Sie dies alshello-tabs/types/index.d.ts:
hello-tabs/types/index.d.ts
Zeigen Sie das Manifest auf die Deklaration
Umclaude plugin validate zu lassen, Ihren Code gegen diese Datei zu überprüfen, fügen Sie ein types Feld zum Manifest mit seinem Pfad hinzu:
hello-tabs/.claude-plugin/plugin.json
Definieren, lesen und schreiben Sie einen Wert
In Ihrem Modul definieren Sie jeden Wert mit einem Standard, lesen ihn beim Zeichnen und schreiben ihn von einem Callback.atom benennt einen Wert und seinen Standard, read gibt ihn zurück, und update schreibt ihn. Die drei Helfer rufen $.state.get und $.state.set für Sie auf:
ui.render Hook count gelesen hat, führt Claude Code den Hook jedes Mal erneut aus, wenn die Schaltfläche ihn schreibt.
Drei Regeln gelten für den Code:
- Schreiben Sie
pluginundkeyals Literal-Strings:claude plugin validateliest sie aus Ihrer Quelle - Deklarieren Sie jeden Wert in der Typendatei: sonst schlägt die Validierung mit
hello-tabs.count is not declaredfehl - Schreiben Sie von einem Callback oder einem anderen Ereignis-Hook: ein
ui.renderHook kann Status lesen und kann ihn nicht schreiben, daher schreiben Sie vononPress,onSubmitoder einem Hook für ein anderes Ereignis
Ändern Sie hello-tabs, um $.state zu verwenden
Um count in hello-tabs in $.state zu verschieben, ändern Sie jede Zeile, die ihn verwendet:
- Am Anfang des Moduls: fügen Sie die
importZeile hinzu, und ersetzen Sielet count = 0mit deratomZeile - Im
ui.renderHook: fügen Sie diereadZeile vortabButtonhinzu, und zeichnen Sie'Count: ' + nimText - Im Add one Button: ersetzen Sie
onPressmit dem aus Speichern Sie aus mehr als einer Sitzung, das die Anzahl speichert sowie schreibt - Im
session.startHook: ersetzen Sie die zwei Zeilen, diesavedlesen, mit demloadCountAufruf aus Laden Sie einen gespeicherten Wert erneut nach/clear
redraw für die Tab-Schaltflächen, da tab immer noch eine Variable ist.
Laden Sie einen gespeicherten Wert erneut nach /clear
Wenn Ihr Mod einen gespeicherten Wert aus $.store in $.state bei session.start kopiert, muss er ihn nach /clear, /resume oder /branch erneut kopieren. Diese Befehle setzen jeden $.state Wert auf seinen Standard zurück, und session.start wird nicht erneut ausgelöst. classic.SessionStart wird nach jedem ausgelöst, mit e.source auf clear, resume oder fork gesetzt, daher kopieren Sie den Wert erneut in einem Hook darauf. Sonst zeigt Ihre Zeichnung den Standard, und ein Callback, der den $.state Wert speichert, schreibt den Standard über das, was Sie gespeichert haben.
Dieser Code lädt count aus beiden Hooks. Es baut auf der $.state Version von hello-tabs auf, wo count ein Atom ist und update importiert wird. Setzen Sie loadCount über register, und fügen Sie den loadCount Aufruf zum session.start Hook hinzu, den Sie bereits haben. classic.SessionStart wird auch beim Start und nach Verdichtung ausgelöst, was $.state nicht zurückgesetzt, daher hält der Filter auf source den Hook zu den drei Resets:
/clear und nicht 0, und der nächste Druck von Add one addiert zur gespeicherten Anzahl.
loadCount schreibt den gespeicherten Wert über den in $.state, und session.start wird jedes Mal ausgelöst, wenn das Modul neu geladen wird. Um den Store nicht hinter sich zu lassen, speichern Sie bei jeder Änderung, wie die Add one Schaltfläche tut.
Um den Reload ohne eine Sitzung zu überprüfen, testen Sie die Zeichnung nach /clear.
Speichern Sie aus mehr als einer Sitzung
Jede Sitzung auf Ihrem Computer, die Ihren Mod ausführt, teilt einen$.store. Ein get gefolgt von einem set ist nicht atomar. Wenn zwei Sitzungen jeweils einen Wert lesen, ihn ändern und zurückschreiben, rennen sie, und der zweite Schreib ersetzt den ersten.
Zwei Auswahlmöglichkeiten machen das weniger wahrscheinlich:
- Geben Sie jedem Element seinen eigenen Schlüssel: ein
setändert nur seinen eigenen Schlüssel, daher überschreiben Sitzungen, die verschiedene Schlüssel schreiben, sich nicht gegenseitig - Lesen Sie erneut direkt vor dem Schreiben: für einen Wert, den mehrere Sitzungen ändern,
getden Schlüssel im Callback und erstellen Sie den neuen Wert daraus, nicht aus einer Kopie, die Sie beisession.startgeladen haben. Ein Schreib einer anderen Sitzung geht immer noch verloren, wenn er zwischen Ihremgetund Ihremsetlandet.
Nächste Schritte
- Reagieren Sie auf Ereignisse: speisen Sie Ihre Zeichnung aus Tool-Calls und Turns
- Verwenden Sie die Mods API: speisen Sie Ihre Zeichnung aus Timern und Modell-Aufrufen
- Testen Sie eine Zeichnung: drücken Sie Ihre Schaltflächen aus einem Test auf mehr als einer Oberfläche
- Render-Sites und Elemente: jede Site’s Props und jedes Element’s Props