在使用 MobX 和 React 的 observer 组件时,MobX 的响应机制决定了何时会更新组件。在以下情况下,修改值会导致组件更新或不会更新:
组件会更新的情况
-
直接修改可观察属性:
- 当你直接修改一个 MobX 的可观察属性时,任何依赖该属性的
observer组件都会自动重新渲染。
import { observable } from 'mobx'; import { observer } from 'mobx-react'; class Store { @observable counter = 0; increment() { this.counter += 1; // 更改可观察属性 } } const store = new Store(); const CounterComponent = observer(() => { return ( <div> <p>Counter: {store.counter}</p> <button onClick={() => store.increment()}>Increment</button> </div> ); }); - 当你直接修改一个 MobX 的可观察属性时,任何依赖该属性的
-
计算值的变化:
- 当所依赖的计算值被更改时。如果一个
observer组件依赖于某个计算值,且计算值的依赖发生变化,则该组件会更新。
import { computed } from 'mobx'; class Store { @observable numbers = [1, 2, 3]; @computed get sum() { return this.numbers.reduce((acc, num) => acc + num, 0); } } const store = new Store(); const SumComponent = observer(() => { return <div>Sum: {store.sum}</div>; // 依赖计算值 }); - 当所依赖的计算值被更改时。如果一个
-
使用
autorun和reaction:- 在 MobX 中,使用
autorun和reaction处理的副作用会在其依赖发生变化时自动触发。
import { reaction } from 'mobx'; reaction( () => store.counter, (counter) => { console.log(`Counter changed: ${counter}`); } ); - 在 MobX 中,使用
组件不会更新的情况
-
未定义为可观察的属性:
- 如果你修改了一个非可观察的属性,依赖该属性的组件不会重新渲染。例如,对于类中的普通属性,MobX 无法跟踪其变化。
class Store { counter = 0; // 非可观察属性 increment() { this.counter += 1; // 改变非可观察属性,不会触发更新 } } -
使用 props:
- 如果
observer组件的 props 未处于可观察状态并且未被修改,即使其父组件的状态发生变化,该组件也不会更新。
- 如果
-
直接修改数组对象而未使用 MobX 的方法:
- 如果你直接修改 MobX 可观察数组的内容而不是使用 MobX 提供的方法来更新数组(如
push、splice等),可能会导致组件不更新。
class Store { @observable items = []; updateItem(id, newValue) { const item = this.items.find(i => i.id === id); item.value = newValue; // 直接修改对象属性,不会触发更新 // 应该使用 `this.items` 的方法,如:`this.items = [...this.items];` 重新创建引用 } } - 如果你直接修改 MobX 可观察数组的内容而不是使用 MobX 提供的方法来更新数组(如
-
深层嵌套的对象:
- 对于嵌套的可观察对象,若你不使用 MobX 的
@observable装饰器标记内部属性,或者未在组件中显式访问这些属性,该组件可能不会响应更新。
- 对于嵌套的可观察对象,若你不使用 MobX 的
-
不使用
observer:- 如果组件没有被
observer装饰,虽然内部状态变化,但组件本身不会更新。
- 如果组件没有被
总结
在使用 MobX 和 Observer 组件时,关键是确保你对状态的修改准确且遵循 MobX 的响应式设计原则。确保可观察的属性被正确设置,使用合适的方法更改状态,以及要注意深层嵌套的数据结构。当遵循这些原则时,MobX 将做到高效且自动化组件更新。