Signals ist eine Performant State Management Library mit zwei Hauptzielen:
Lesen Sie den Ankündigungsbeitrag, um mehr darüber zu erfahren, welche Probleme Signale löst und wie es sich erholt.
# Just the core library
npm install @preact/signals-core
# If you're using Preact
npm install @preact/signals
# If you're using React
npm install @preact/signals-react
# If you're using Svelte
npm install @preact/signals-core
signal(initialValue)
signal.peek()
computed(fn)
effect(fn)
batch(fn)
untracked(fn)
Die Signal -Bibliothek enthält vier Funktionen, nämlich die Bausteine, um jede geschäftliche Logik zu modellieren, an die Sie sich vorstellen können.
signal(initialValue)
Die signal
erstellt ein neues Signal. Ein Signal ist ein Container für einen Wert, der sich im Laufe der Zeit ändern kann. Sie können den Wert eines Signals lesen oder Wertaktualisierungen abonnieren, indem Sie auf die .value
zugreifen.
import { signal } from "@preact/signals-core" ;
const counter = signal ( 0 ) ;
// Read value from signal, logs: 0
console . log ( counter . value ) ;
// Write to a signal
counter . value = 1 ;
Das Schreiben in ein Signal erfolgt durch Einstellen der .value
. Das Ändern des Werts eines Signals synchron aktualisiert jeden berechneten und effekt, der von diesem Signal abhängt, und sicherzustellen, dass Ihr App -Status immer konsistent ist.
signal.peek()
In dem seltenen Fall, dass Sie einen Effekt haben, der auf ein anderes Signal basierend auf dem vorherigen Wert schreiben sollte. Sie möchten jedoch nicht , dass der Effekt dieses Signal abonniert wird, können Sie den vorherigen Wert eines Signals über signal.peek()
lesen.
const counter = signal ( 0 ) ;
const effectCount = signal ( 0 ) ;
effect ( ( ) => {
console . log ( counter . value ) ;
// Whenever this effect is triggered, increase `effectCount`.
// But we don't want this signal to react to `effectCount`
effectCount . value = effectCount . peek ( ) + 1 ;
} ) ;
Beachten Sie, dass Sie nur signal.peek()
wenn Sie es wirklich brauchen. Das Lesen eines Signalwerts über signal.value
ist in den meisten Szenarien die bevorzugte Art und Weise.
computed(fn)
Daten werden häufig aus anderen vorhandenen Daten abgeleitet. Mit der computed
Funktion können Sie die Werte mehrerer Signale zu einem neuen Signal kombinieren, das auf zusätzliche Computer reagiert oder sogar verwendet werden kann. Wenn die Signale innerhalb einer berechneten Rückrufänderung zugänglich sind, wird der berechnete Rückruf erneut ausgezeichnet und sein neuer Rückgabewert wird zum Wert des berechneten Signals.
import { signal , computed } from "@preact/signals-core" ;
const name = signal ( "Jane" ) ;
const surname = signal ( "Doe" ) ;
const fullName = computed ( ( ) => name . value + " " + surname . value ) ;
// Logs: "Jane Doe"
console . log ( fullName . value ) ;
// Updates flow through computed, but only if someone
// subscribes to it. More on that later.
name . value = "John" ;
// Logs: "John Doe"
console . log ( fullName . value ) ;
Jedes Signal, auf das in der Rückruffunktion des computed
zugegriffen wird, wird automatisch als Abhängigkeit des Computersignals abonniert und verfolgt.
effect(fn)
Die effect
ist das letzte Stück, das alles reaktiv macht. Wenn Sie in der Rückruffunktion auf ein Signal zugreifen, wird dieses Signal und jede Abhängigkeit des Signals aktiviert und abonniert. In dieser Hinsicht ist es dem computed(fn)
sehr ähnlich. Standardmäßig sind alle Updates faul, sodass nichts aktualisiert wird, bis Sie im effect
auf ein Signal zugreifen.
import { signal , computed , effect } from "@preact/signals-core" ;
const name = signal ( "Jane" ) ;
const surname = signal ( "Doe" ) ;
const fullName = computed ( ( ) => name . value + " " + surname . value ) ;
// Logs: "Jane Doe"
effect ( ( ) => console . log ( fullName . value ) ) ;
// Updating one of its dependencies will automatically trigger
// the effect above, and will print "John Doe" to the console.
name . value = "John" ;
Sie können einen Effekt zerstören und sich von allen Signalen abmelden, die er abonniert hat, indem Sie die zurückgegebene Funktion aufrufen.
import { signal , computed , effect } from "@preact/signals-core" ;
const name = signal ( "Jane" ) ;
const surname = signal ( "Doe" ) ;
const fullName = computed ( ( ) => name . value + " " + surname . value ) ;
// Logs: "Jane Doe"
const dispose = effect ( ( ) => console . log ( fullName . value ) ) ;
// Destroy effect and subscriptions
dispose ( ) ;
// Update does nothing, because no one is subscribed anymore.
// Even the computed `fullName` signal won't change, because it knows
// that no one listens to it.
surname . value = "Doe 2" ;
Der Effekt -Rückruf kann eine Reinigungsfunktion zurückgeben. Die Reinigungsfunktion wird einmal ausgeführt, entweder wenn der Effektrückruf als nächstes aufgerufen wird oder wenn der Effekt entsorgt wird, je nachdem, was zuerst passiert.
import { signal , effect } from "@preact/signals-core" ;
const count = signal ( 0 ) ;
const dispose = effect ( ( ) => {
const c = count . value ;
return ( ) => console . log ( `cleanup ${ c } ` ) ;
} ) ;
// Logs: cleanup 0
count . value = 1 ;
// Logs: cleanup 1
dispose ( ) ;
batch(fn)
Mit der batch
-Funktion können Sie mehrere Signalschreibungen in ein einzelnes Update kombinieren, das am Ende ausgelöst wird, wenn der Rückruf abgeschlossen ist.
import { signal , computed , effect , batch } from "@preact/signals-core" ;
const name = signal ( "Jane" ) ;
const surname = signal ( "Doe" ) ;
const fullName = computed ( ( ) => name . value + " " + surname . value ) ;
// Logs: "Jane Doe"
effect ( ( ) => console . log ( fullName . value ) ) ;
// Combines both signal writes into one update. Once the callback
// returns the `effect` will trigger and we'll log "Foo Bar"
batch ( ( ) => {
name . value = "Foo" ;
surname . value = "Bar" ;
} ) ;
Wenn Sie auf ein Signal zugreifen, an das Sie früher im Rückruf geschrieben haben, oder auf ein berechnetes Signal zugreifen, das von einem anderen Signal ungültig gemacht wurde, aktualisieren wir nur die erforderlichen Abhängigkeiten, um den aktuellen Wert für das Signal zu erhalten, aus dem Sie gelesen werden. Alle anderen ungültig erklärten Signale aktualisieren am Ende der Rückruffunktion.
import { signal , computed , effect , batch } from "@preact/signals-core" ;
const counter = signal ( 0 ) ;
const double = computed ( ( ) => counter . value * 2 ) ;
const triple = computed ( ( ) => counter . value * 3 ) ;
effect ( ( ) => console . log ( double . value , triple . value ) ) ;
batch ( ( ) => {
counter . value = 1 ;
// Logs: 2, despite being inside batch, but `triple`
// will only update once the callback is complete
console . log ( double . value ) ;
} ) ;
// Now we reached the end of the batch and call the effect
Chargen können verschachtelt werden und Updates werden gespült, wenn der äußerste Batch -Anruf abgeschlossen ist.
import { signal , computed , effect , batch } from "@preact/signals-core" ;
const counter = signal ( 0 ) ;
effect ( ( ) => console . log ( counter . value ) ) ;
batch ( ( ) => {
batch ( ( ) => {
// Signal is invalidated, but update is not flushed because
// we're still inside another batch
counter . value = 1 ;
} ) ;
// Still not updated...
} ) ;
// Now the callback completed and we'll trigger the effect.
untracked(fn)
Wenn Sie einen Rückruf erhalten, der einige Signale lesen kann, aber Sie sie nicht abonnieren möchten, können Sie nicht untracked
um zu verhindern, dass Abonnements stattfinden.
const counter = signal ( 0 ) ;
const effectCount = signal ( 0 ) ;
const fn = ( ) => effectCount . value + 1 ;
effect ( ( ) => {
console . log ( counter . value ) ;
// Whenever this effect is triggered, run `fn` that gives new value
effectCount . value = untracked ( fn ) ;
} ) ;
MIT
, siehe Lizenzdatei.