如何使用mobx观察可观察数组上的object.property变化

问题描述 投票:0回答:1

我正在使用reactjs和mobx。我有一个可观察的 Item 对象数组,我试图通过观察数组中对象的属性来显示它们并“实时”显示属性更改。这些更改不是由任何组件上的单击事件触发的,而是由对 API 调用的响应触发的。

我知道数组中对象的属性更改不会触发整个列表重新渲染(这很好),但我无法让它重新渲染应该观察属性的单个 Item 组件项目对象。

我尝试了几种方法来使数组中的 Item 对象可观察,但这些方法都不适合我:

  • 从 Item 的构造函数中调用 'extendObservable()
  • 将 props.item 分配给用“@observable”装饰的类成员
  • 调用 observable 构造函数并传入 item 对象,如下所示:const item = observable(item)
  • 将“hasUnreadData”字段作为单独的 prop 传递,并通过“observable.box(item.hasUnreadData)”使其可观察。

这是一些简化的示例代码(打字稿):

class Item {

  id : string
  hasUnreadData : boolean

  constructor (data: any) {
    this.id = data.id;
    // false by default
    this.hasUnreadData = data.hasUnreadData;
  }

}

@observable items: Item[];

// observes the array and re-renders when items are added/removed (this works)
@observer
class ItemListComponent extends React.Component {
  render() {
    return (
      <List> {
        items.map((item: Item, index) => {

          <ItemComponent key={item.id} itemModel={item} />

        }
      }
    )
  }
}

// should observe the 'hasUnreadData' flag and apply different styles when it re-renders (but this does not work, it only displays the initial state)
@observer
class ItemComponent extends React.Component {
  render() {
    const item = this.props.item;
    return (
      <ListItem button divider selected={item.hasUnreadData} />
    )

  }
}


// imagine this is a promise from an API call
API.fetchData().then((itemId: string) => {
  itemToUpdate = items.find(i => i.id === itemId);
  itemToUpdate.hasUnreadData = true; 
  // this does not trigger the ItemComponent to render again as expected.
});

我是否需要克隆或以其他方式“重新创建”Item 对象来触发渲染?或者我在这里犯了一个明显的错误?任何帮助表示赞赏。

reactjs mobx
1个回答
0
投票

另外,我知道这是一个老话题,但这只是我发现的一个话题,这似乎也是我的问题。 (我的情况是,如果您仍在使用旧的 MOBX)。 所以这解决了我的问题。 还要确保您的应用程序的某些地方不使用变量组件,而是使用函数组件!

// imagine this is a promise from an API call
API.fetchData().then((itemId: string) => {
  itemToUpdate = items.find(i => i.id === itemId);
      runInAction(() => {
              itemToUpdate.hasUnreadData = true; 
          }); 
});

尝试使用 mobx 的

runInAction()
方法来实现

© www.soinside.com 2019 - 2024. All rights reserved.