建立自定義可觀察物件 {🚀}
有時您可能希望有更多資料結構或其他事物(例如串流)可以在反應式計算中使用。透過使用 atom(MobX 內部用於所有可觀察資料類型的類別)可以輕鬆實現這一點。Atom 可用於向 MobX 發送信號,表示某些可觀察資料源已被觀察或更改,MobX 將在 atom 被使用和不被使用時通知它。
提示:在許多情況下,您可以透過建立一般的可觀察物件,並使用
onBecomeObserved
工具在 MobX 開始追蹤它時收到通知,來避免建立自己的 atom。
以下範例示範如何建立一個可觀察的 Clock
,它會傳回目前的日期時間,然後可以在反應式函數中使用。這個時鐘只有在有人觀察它的情況下才會實際運作。
此範例示範了 Atom
類別的完整 API。如需更多資訊,請參閱 createAtom
。
import { createAtom, autorun } from "mobx"
class Clock {
atom
intervalHandler = null
currentDateTime
constructor() {
// Creates an atom to interact with the MobX core algorithm.
this.atom = createAtom(
// 1st parameter:
// - Atom's name, for debugging purposes.
"Clock",
// 2nd (optional) parameter:
// - Callback for when this atom transitions from unobserved to observed.
() => this.startTicking(),
// 3rd (optional) parameter:
// - Callback for when this atom transitions from observed to unobserved.
() => this.stopTicking()
// The same atom transitions between these two states multiple times.
)
}
getTime() {
// Let MobX know this observable data source has been used.
//
// reportObserved will return true if the atom is currently being observed
// by some reaction. If needed, it will also trigger the startTicking
// onBecomeObserved event handler.
if (this.atom.reportObserved()) {
return this.currentDateTime
} else {
// getTime was called, but not while a reaction was running, hence
// nobody depends on this value, and the startTicking onBecomeObserved
// handler won't be fired.
//
// Depending on the nature of your atom it might behave differently
// in such circumstances, like throwing an error, returning a default
// value, etc.
return new Date()
}
}
tick() {
this.currentDateTime = new Date()
this.atom.reportChanged() // Let MobX know that this data source has changed.
}
startTicking() {
this.tick() // Initial tick.
this.intervalHandler = setInterval(() => this.tick(), 1000)
}
stopTicking() {
clearInterval(this.intervalHandler)
this.intervalHandler = null
}
}
const clock = new Clock()
const disposer = autorun(() => console.log(clock.getTime()))
// Prints the time every second.
// Stop printing. If nobody else uses the same `clock`, it will stop ticking as well.
disposer()