为什么我对(mobx)extendObservable的调用不会触发重新渲染?

时间:2017-03-11 04:56:16

标签: javascript reactjs mobx

这是代码 - 非常确定它是关于extendObservable的东西,我只是不知道,但现在已经盯着它看了很长一段时间。当addSimpleProperty运行时,它似乎更新了对象,但它没有触发渲染。

const {observable, action, extendObservable} = mobx;
const {observer} = mobxReact;
const {Component} = React;
class TestStore {
    @observable mySimpleObject = {};

    @action addSimpleProperty = (value) => {
        extendObservable(this.mySimpleObject, {newProp: value});
    }
}

@observer
class MyView extends Component {
constructor(props) {
    super(props);
    this.handleAddSimpleProperty = this.handleAddSimpleProperty.bind(this);
}
handleAddSimpleProperty(e) {
    this.props.myStore.addSimpleProperty("newpropertyvalue");
}

render() { 
    var simpleObjectString =JSON.stringify(this.props.myStore.mySimpleObject);
    return (<div>     
       <h3> Simple Object</h3>
       {simpleObjectString}
       <br/>
       <button onClick={this.handleAddSimpleProperty}>Add Simple Property</button>
    </div>);
    }
}

const store = new TestStore();
ReactDOM.render(<MyView myStore={store} />,    document.getElementById('mount'));
store.mySimpleObject = {prop1: "property1", prop2: "property2"};

1 个答案:

答案 0 :(得分:2)

此问题出现在文档的Common pitfalls & best practices部分:

  

MobX可观察对象不会检测或响应属性分配   之前没有被宣布为可观察的。所以MobX可观察对象   充当具有预定义键的记录。您可以使用   extendObservable(target, props)引入新的可观察性   对象的属性。但是对象迭代器如for .. in或   Object.keys()不会自动对此做出反应。如果你需要一个   动态键控对象,例如按id,create存储用户   可观察的_map_s使用   observable.map

因此,不要在可观察对象上使用extendObservable,而只需向可观察的地图添加新密钥。

示例

const {observable, action} = mobx;
const {observer} = mobxReact;
const {Component} = React;
class TestStore {
  mySimpleObject = observable.map({});

  @action addSimpleProperty = (value) => {
    this.mySimpleObject.set(value, {newProp: value});
  }
}

@observer
class MyView extends Component {
  constructor(props) {
    super(props);
    this.handleAddSimpleProperty = this.handleAddSimpleProperty.bind(this);
  }
  handleAddSimpleProperty(e) {
    this.props.myStore.addSimpleProperty("newpropertyvalue");
  }

  render() { 
    var simpleObjectString = this.props.myStore.mySimpleObject.values();
    return (
      <div>     
        <h3> Simple Object</h3>
        {simpleObjectString.map(e => e.newProp)}
        <br/>
        <button onClick={this.handleAddSimpleProperty}>Add Simple Property</button>
     </div>
    );
  }
}

const store = new TestStore();
ReactDOM.render(<MyView myStore={store} />, document.getElementById('mount'));