MobX observables 变化并不总是触发观察者组件渲染

MobX observables change do not always trigger observer components render

我的项目是基于 React 构建的,并且使用 Mobx 进行状态管理。 我们没有使用装饰器,所以需要观察可观察对象的组件需要用以下方式包装:

import React from 'react';
import {observer} from 'mobx-react';
import MyComponent from '../app/my-component.jsx';
import myFilter from './my-filters.jsx';

export default observer(() => {
  return <MyComponent filter={myFilter}/>;
});

组件 MyComponent 正在接收 observables 作为道具:

static propTypes() {
    return {
      myFilter: React.PropTypes.function.isRequired
    };
  }

并且在render方法中使用:

render() {
  if (this.props.myFilter.filterValue1 !== null) {
    // some code here
  }
}

myFilter 在这种情况下是可观察的,看起来有点像这样:

import {observable} from 'mobx';

const myFilter = observable({
  filterValue1: null,
  filterValue2: null,
  addOrRemoveItem() {
    // some function here
  }
});

export default myFilter;

在这种情况下,如果某些组件改变 myFilter,接收可观察对象作为道具的观察者 MyComponent 并不总是重新渲染。在某些情况下,这可以通过在组件调用之前通过属性寻址可观察对象来解决。例如:

export default observer(() => {
  console.log(myFilter.filterValue1);
  return <MyComponent filter={myFilter}/>;
});

但这并不稳定。 是否有有效的解决方法来避免这种情况?

宣布MyComponent为观察员。

app/my-component.jsx 中的导出应该如下所示

export default observer(MyComponent);

这段代码

export default observer(() => {
  return <MyComponent filter={myFilter}/>;
});

将一个匿名无状态组件,而不是MyComponent,变成一个观察者。

MobX 文档清楚地表明您需要将 observer 应用于所有呈现可观察数据的组件,否则您将遇到问题。

另一种解决问题的方法是将纯数据从这个匿名无状态组件传递到 MyComponent

export default observer(() => {
  return <MyComponent filterValue1={myFilter.filterValue1}/>;
});

这种方式将重新渲染 MyComponent,因为每次重新渲染其父组件时它都会收到新的道具。

Alik 说得对,你也需要 MyComponent 才能成为观察者。

否则,您的代码 <MyComponent filter={myFilter}/> 在您拥有的唯一可观察对象中意味着您只想在 myFilter 对象(即对它的引用)更改时刷新。它不访问其任何属性,因此当这些属性更改时不需要刷新。这就是为什么当您访问 console.log 语句中的 filterValue1 属性 时您的组件被刷新的原因。