以下の内容はhttps://uga-box.hatenablog.com/entry/2024/10/31/000000より取得しました。


【Mobx】変更を検知する場合としない場合を理解する

ReactとMobxを使う上で変更を検知する場合としない場合を理解する

このことのヒントは以下に記載がある

mobx.js.org

原則observerオブジェクトから値を取るのはできるだけ遅くする

Mobxはobserverオブジェクト参照を可能な限り持ち回した方が効果的に機能する

例えば、以下のような実装をした場合はうまくいかない

const TimerView = observer(({ secondsPassed }) => <span>Seconds passed: {secondsPassed}</span>)

React.render(<TimerView secondsPassed={myTimer.secondsPassed} />, document.body)

observerでラップしたTimerViewにはobserverオブジェクトそのものではなく、observerオブジェクトの.secondsPassedを渡してしまっているため、変更が検知できない状態になっている

なぜ変更が検知できなくなるかの理由は以下のページに書かれていて、MobXは値ではなくプロパティのアクセスを追跡するためであると書かれている

mobx.js.org

詳しく説明するために、次の観測可能なインスタンスがあるとする

class Message {
    title
    author
    likes
    constructor(title, author, likes) {
        makeAutoObservable(this)
        this.title = title
        this.author = author
        this.likes = likes
    }

    updateTitle(title) {
        this.title = title
    }
}

let message = new Message("Foo", { name: "Michel" }, ["Joe", "Sara"])

メモリ内では次のようになっていて、このうち、観測可能なプロパティは緑色のボックスである

例えば、message.updateTitle("Bar")という関数を実行した場合、message.titleは"Foo"への参照が解除され、"Bar"を参照する

Mobxはこの変更を検出するため、message.titleを参照している関数は正常に機能する

よって、オブジェクト参照をして値を渡すのではなく、オブジェクト参照をできる限り渡した方が良い

他に変更が検知されない例

変数に別のオブジェクトを再代入する

autorun(() => {
    console.log(message.title)
})
message = new Message("Bar", { name: "Martijn" }, ["Felicia", "Marcus"])

message自体は観測可能ではないため、再代入しても何も反応しない

外部で変数を定義した場合

let title = message.title
autorun(() => {
    console.log(title)
})
message.updateMessage("Bar")

外部で変数を定義した瞬間の値Fooを持ったtitleは観測可能ではないため、反応しない

配列の範囲外のインデックスにアクセスした場合

autorun(() => {
    console.log(message.likes[0])
})
message.likes.push("Jennifer")

まだ何も格納されていない配列インデックスは観測可能ではないため、反応しない

参照する前にindex < lengthであることを確認する必要がある

配列インデックスの変更と配列自体の参照

autorun(() => {
    message.likes
})
message.likes.push("Jennifer")

message.likes自体に変更があったわけではないので、反応しない




以上の内容はhttps://uga-box.hatenablog.com/entry/2024/10/31/000000より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14