ReactとMobxを使う上で変更を検知する場合としない場合を理解する
このことのヒントは以下に記載がある
原則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は値ではなくプロパティのアクセスを追跡するためであると書かれている
詳しく説明するために、次の観測可能なインスタンスがあるとする
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自体に変更があったわけではないので、反応しない