商店更新时组件不会重新呈现-Mobx

时间:2018-12-22 13:55:12

标签: javascript reactjs mobx mobx-react

我有三个组成部分;表单,预览和AppStore。单击“表单”中的按钮会将项目添加到商店。这似乎工作得很好,但是即使商店有@observer装饰器,但当商店发生更改时,Preview组件中的列表也不会更新/重新呈现,这一点似乎不错。我想念什么?

窗体具有按钮和处理程序功能,可将项目添加到商店:

    @inject('AppStore')
    @observer class Form extends React.Component{

      handleAddItem= (item) =>{
        const {AppStore} = this.props;
        AppStore.addItem(item);
        console.log(AppStore.current.items)
      }

      render(){
        return(
              <button onClick={() => this.handleAddItem('Another Item')}>Add Item</button>

        )}
    }

预览会在各个项目之间进行映射(我使用的是拖放操作,因此我的代码可能看起来有些奇怪)

  @inject('AppStore')
  @observer class Preview extends React.Component

...

return(
   <ul>
       {items.map((value, index) => (
        <SortableItem key={`item-${index}`} index={index} value={value} />
        ))}
  </ul>)

...

  return <SortableList items={AppStore.current.items} onSortEnd={this.onSortEnd} />;

这是商店:

import { observable, action, computed } from "mobx";

class AppStore {
  @observable other = {name: '', desc:'', items: [ 'item 1', 'item 2', 'item 3'], id:''}
  @observable current = {name: '', desc:'', items: [ 'item 1', 'item 2', 'item 3'], id:''}

  @action addItem = (item) => {
    this.current.items.push(item)
  }
}

const store = new AppStore();
export default store;

2 个答案:

答案 0 :(得分:0)

我相当确定这是MobX不会将可观察性一直扩展到current.items数组中的情况。

Objects in MobX会在首次构造/初始化时扩展可观察性-因此,current.items是可观察的属性,从某种意义上来说,如果将其值更改为其他原语,则组件将重新呈现。 / p>

例如:

current.items = 1; // changing it from your array to some totally new value
current.items = []; // this _might_ also work because it's a new array

类似地,如果AppStore具有您正在更改的顶级可观察的items,则调用items.push()也可以。

class AppStore {
    @observable items = [];

    @action additem = (item) => {
        this.items.push(item);
    }
}

您遇到的问题是items被埋在可观察对象的深处,因此将项目推入current.items数组不会以某种方式更改属性的值MobX可以检测到。

众所周知,这非常令人困惑,common MobX pitfalls有时很难理解。

另请参阅对象文档中的以下行:

  

将仅使普通对象可观察。对于非普通物体   被认为是构造函数负责初始化   可观察的属性。

答案 1 :(得分:0)

尝试将您的操作替换为:

@action addItem = (item) => {
   this.current.items = this.current.items.concat([item]);
}

这里不用使用push来使属性发生突变,而使用concat来合并两个数组,并返回一个带有新引用的MobX可以响应的全新数组。