信號是一個具有兩個主要目標的表現國家管理庫:
閱讀公告文章,以了解有關哪些問題解決的更多信息以及如何解決。
# 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)
信號庫公開了四個功能,這是建模您可以想到的任何業務邏輯的構建塊。
signal(initialValue)
signal
功能會產生一個新信號。信號是一個可以隨時間變化的值的容器。您可以通過訪問其.value
屬性來讀取信號的值或訂閱值更新。
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 ;
寫入信號是通過設置其.value
屬性來完成的。更改信號的值同步更新了取決於該信號的每個計算和效果,以確保您的應用程序狀態始終保持一致。
signal.peek()
在極少數情況下,您應根據上一個值將其寫入另一個信號,但是您不希望訂閱該信號的效果,您可以通過signal.peek()
讀取信號的先前值。
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 ;
} ) ;
請注意,如果您確實需要它,則應僅使用signal.peek()
。通過signal.value
讀取信號的值。值是大多數情況下的首選方式。
computed(fn)
數據通常源自其他現有數據。 computed
函數使您可以將多個信號的值結合到一個可以反應甚至由其他計算機使用的新信號中。當從計算的回調更改中訪問的信號時,重新執行了計算的回調,其新返回值將成為計算信號的值。
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 ) ;
computed
的回調函數中訪問的任何信號將自動訂閱並跟踪為計算信號的依賴性。
effect(fn)
effect
函數是使所有事物都反應的最後一部分。當您在其回調函數中訪問信號時,該信號和所述信號的每個依賴性將被激活並訂閱。在這方面,它與computed(fn)
非常相似。默認情況下,所有更新都很懶惰,因此在您訪問信號內部effect
之前,什麼都不會更新。
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" ;
您可以通過調用返回的功能來破壞效果並取消訂閱其訂閱的所有信號。
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" ;
效果回調可能會返回清理功能。在接下來要調用效果回調的效果回調或效果被處置時,清理功能會運行一次。
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)
batch
功能允許您將多個信號寫入一個單個更新中,該更新在回調完成時在末尾觸發。
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" ;
} ) ;
當您訪問回調內部寫入的信號,或訪問由另一個信號無效的計算信號時,我們只會更新必要的依賴項,以獲取您從中讀取的信號的當前值。所有其他無效的信號將在回調函數的末尾進行更新。
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
批處理可以嵌套,並在最外面的批次調用完成後匯總更新。
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)
如果您收到可以讀取一些信號的回調,但您不想訂閱它們時,您可以使用untracked
來防止任何訂閱發生。
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
,請參閱許可證文件。