MobX - 当我可以在将数据注入 React 组件时使用“inject”时,为什么我应该使用“observer”

2024-04-29

MobX 文档建议我应该使用observer在我的所有组件上。然而,通过使用注入,我可以更细粒度地控制哪些数据导致组件的重新渲染。

我的理解是我observer,最后一次渲染中所有访问的可观察量的更改将导致重新渲染,即使可观察量嵌套在数据存储深处,而inject仅当注入器函数中访问的可观察量发生变化时才重新渲染。

例如:

class Store{
  @observable data = {
    nestedData: {
      deepData: 'my_data'
    }
  }
}

const store = new Store();

... Assume the store is injected using <Provider /> component

// This will cause re-render when the data object changes
// for example: store.data = { new_data: 'new_data' }
@inject(stores => {
  return { data: stores.dataStore.data }; 
})
class MyComponent extends Component {  }

// This will re-render on change of the data object, but also
// on change of nestedData and deepData properties
@inject(stores => {
  return { data: stores.dataStore.data }; 
})
@observer
class MyComponent extends Component {  }

有人可以证实我对此的理解吗?

在我看来,最好只使用inject因为它为您提供了更多控制权,并且可以防止不必要的重新渲染。如果数据嵌套得很深,您可以创建一个计算属性,从深层结构获取并准备数据,然后将该属性注入到组件中。

使用其中一种相对于另一种是否还有其他优点/缺点


我相信你的评估是正确的。为了清楚起见,让我尝试重新表述一下:

@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.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MobX - 当我可以在将数据注入 React 组件时使用“inject”时,为什么我应该使用“observer” 的相关文章

随机推荐