我相信你的评估是正确的。为了清楚起见,让我尝试重新表述一下:
@observer https://github.com/mobxjs/mobx-react#observercomponentclass跟踪哪些可观察量被使用render
当这些值之一发生变化时,自动重新渲染组件。
我们应该注意到@observable
使用的值render
可能深深地嵌套在给定的内部prop
,根据你的例子:
class Store{
@observable data = {
nestedData: {
// changes to `deepData` would theoretically re-render any observer
deepData: 'my_data'
}
}
}
与观察者一起,所有访问的变化
最后一次渲染中的可观察量将导致重新渲染,即使
observable 嵌套在数据存储深处
Bingo!
虽然有一个怪癖observable
,正如您稍后会看到的...
另一方面你有@inject https://github.com/mobxjs/mobx-react#provider-and-inject这使得组件可用(通过props
)由a定义的特定数据结构Provider
.
例如:
@inject('title')
class MyComponent extends React.Component {
render() {
return (<div>{this.props.title}</div>);
}
}
const Container = () => (
<Provider title="This value is passed as a prop using `inject`">
<MyComponent />
</Provider>
);
仅注射
当注入器函数中访问的可观察量发生变化时重新渲染。
Bingo!
inject
仅在以下情况下才会产生重新渲染prop
本身已经认识到变化。
这实际上是同样的问题应该组件更新() https://reactjs.org/docs/react-component.html#shouldcomponentupdate以及深度比较props
- 尽管observer
似乎是效率更高 https://github.com/mobxjs/mobx-react#about-shouldcomponentupdate than shouldComponentUpdate
.
在我看来,最好只使用注入,因为它可以为您提供更多
控制,并可以防止不必要的重新渲染。
我不一定会走那么远……这完全取决于您的代码结构。
如果我将您的原始示例修改为:
class Store{
@observable data = {
nestedData: {}
};
constructor() {
this.data.nestedData.deepData = 'my_data';
}
}
...添加deepData
实际上不会被视为可观察的更改(即重新渲染),因为当我们最初标记时该属性不存在data
作为可观察值。所以这是一个问题。
另一种方法可能是执行以下操作:
class Person {
@observable name = 'John Doe';
}
class Store{
@observable data = null;
constructor() {
this.data = new Person();
}
}
这允许您将可观察值分散到各个类中——所以您可能仍然想注入Store
进入组件(以访问Store.data
但最终任何可观察到的变化都来自更新Person
.