MobX似乎不适合我。我基本上有这两个文件:
@inject("apiDepo")
@observer
class Test extends React.Component {
public render() {
return <div>{this.props.apiDepo.remoteNum}</div>
}
}
// apiDepo.ts
class apiDepo {
@observable private _remoteNum;
@computed get remoteNum() {
console.log("get")
return this._remoteNum || (this.fetchRemoteNum() && undefined);
}
private async fetchRemoteNum() {
const response = await someFuncThatRequestsARemoteNum();
console.log("set")
this._remoteNum = response.remoteNum || 0;
console.log(this);
console.log("remoteNum", this.remoteNum);
}
}
运行它的控制台的输出是
> "get"
> "set"
> { _remoteNum: 0, fetchRemoteNum() } // is missing this.remoteNum
> "remoteNum" undefined // should be 0
随后没有得到。
据我所知,这是MobX应该如何工作的一个非常简单的例子。你得到一个可观察的,它得到了更新,应该调用forceUpdate()(但不是)。
我想知道的是为什么它不能正常工作?上面的实现似乎有什么不对吗?如果没有,是否有人有任何关于它为什么不起作用的线索?
编辑:除了@observer
之外,我没有任何重载componentShouldUpdate的内容编辑2:添加了console.log(this.remoteNum)
答案 0 :(得分:1)
出现问题的路线就在这里:
return this._remoteNum || (this.fetchRemoteNum() && undefined);
原因是,当_remoteNum等于0时,它是假的(因为它将数字转换为布尔值。而0被解释为假)。所以它不会返回数字,但再次调用fetch!通过在每次调用后返回一个新数字,您可以轻松地看到此行为:
const response = await new Promise<number>((resolve) => {
window.setTimeout(() => resolve(this._remoteNum++), 1000);
})
要防止此布尔强制转换,您需要显式比较该值。
所以解决方案是:
@observable _remoteNum: number;
@computed get remoteNum(): number {
if(this._remoteNum != null) {
return this._remoteNum;
} else {
this.fetchRemoteNum() && undefined;
}
}
private async fetchRemoteNum() {
const response = await new Promise<number>((resolve) => {
window.setTimeout(() => resolve(0), 1000);
})
console.log('updated');
this._remoteNum = response;
}
我建议总是使用===或!==而不要让javascript隐式地将值转换为boolean