【问题标题】:MobX observables change do not always trigger observer components renderMobX observables 的变化并不总是触发观察者组件渲染
【发布时间】:2017-06-02 07:02:26
【问题描述】:

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

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 正在接收可观察对象作为道具:

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}/>;
});

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

【问题讨论】:

    标签: reactjs mobx


    【解决方案1】:

    声明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 将被重新渲染,因为它每次重新渲染其父级时都会收到新的道具。

    【讨论】:

      【解决方案2】:

      Alik 是对的,您还需要 MyComponent 成为观察者。

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

      【讨论】:

      • 感谢 gius 和 Alik,这当然解决了渲染问题。想法是将所有观察包装器放在一个地方以便于维护,从而使类保持原样。但可能声明类观察者是唯一的方法。
      猜你喜欢
      • 2017-08-24
      • 1970-01-01
      • 1970-01-01
      • 2019-03-19
      • 1970-01-01
      • 2019-07-14
      • 2023-04-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多