开始使用Mobx& amp;反应并无法让商店更新。单击按钮时出现错误,该按钮应更新“我”。财产:
Store.js:12 Uncaught TypeError: Cannot set property 'me' of null
我的商店:
import { observable } from 'mobx';
class Store {
@observable me;
constructor() {
this.me = 'test';
}
change_me(){
this.me = 'test 1';
console.log(this); // null???
}
}
const store = new Store();
export default store;
组件:
import React from "react";
import { observer } from 'mobx-react';
export default class Layout extends React.Component{
render(){
var store = this.props.store;
return(
<div>
<button onClick={store.change_me}>{store.me}</button>
</div>
)
}
}
我可能错过了一些基本的工作方式,但无法弄清楚。
答案 0 :(得分:2)
是反应执行事件回调,this
为空。由于您只提供onClick
回调change_me
方法,而不是store
作为背景。
您必须自己设置this
上下文。你可以通过以下方式做到这一点
正如@Eduard所说,你可以将它变成箭头功能。 Arrow函数确保this
上下文在函数体中保持不变:
<button onClick={() =>store.change_me()}>{store.me}</button>
您还可以使用bind方法:
<button onClick={store.change_me.bind(store)}>{store.me}</button>
这基本上是一回事。
为什么他们的做法不好?在每次render()
调用时,都会重新创建这些方法。并且可能导致额外的不必要的重新渲染。
mobx提供了一个action.bound
,它使用正确的上下文包装函数:
@mobx.action.bound
change_me(){
this.me = 'test 1';
}
另外,es6类定义允许您自己正确定义此上下文:
@mobx.action
change_me = () => {
this.me = 'test 1';
}
请参阅箭头功能。幕后:而不是在Store
类的原型上定义函数/方法。该方法在constructor
中创建,以便this
上下文变量始终与该类的实例匹配。
这样:
var a = new Store(); // a.me = 'test'
var b = new Store(); // b.me = 'test'
a.change_me = b.change_me; // change_me function contains its own this context.
a.change_me(); // a.me = 'test' b.me = 'test 1'
答案 1 :(得分:1)
我不知道mobx
但是onClick={store.change_me}
是一个问题,因为您在类上使用方法作为函数(没有this
)。你将不得不使用类似的东西:
onClick={event => store.changeMe(event)}
否则与store
的绑定将丢失。
也可能但不太可读:
onClick={store.changeMe.bind(store)}
答案 2 :(得分:1)
正如@Sulthan所提到的,你需要让另一个函数onClick={()=>store.changeMe()}
包装该方法。
第二个问题是您缺少更新值的方法的action
装饰器。 Mobx的工作方式是每个更新属性的方法,需要由@action
进行修饰。以下将解决问题import {action} from 'mobx
,
@action change_me(){
this.me = 'test 1';
}