action
用法:
action(fn)
action(name, fn)
@action classMethod
@action(name) classMethod
@action boundClassMethod = (args) => { body }
@action(name) boundClassMethod = (args) => { body }
任何应用都有action,Actions 可以是修改状态的任何东西。使用 MobX,你可以在你的代码中显式的标记它们,Actions 帮助你更好的组织你的代码结构。它需要一个函数,并之后返回一个其使用untracked
,transaction
和allowStateChanges
包装的函数,建议将它们用于修改可观察的变量或具有任何副作用的任何函数。action
还提供了和开发工具组合使用时的调试信息。
注:如果启用 严格模式,则必须使用action
去操作 state,详见useStrict
。不支持使用@action
装饰器在 ES 5.1 setters (i.e. @action set propertyName
)
有关操作的详细介绍,请参阅 MobX 2.2 发行版说明。
contace-list
项目中的两个示例:
@action createRandomContact() {
this.pendingRequestCount++;
superagent
.get('https://randomuser.me/api/')
.set('Accept', 'application/json')
.end(action("createRandomContact-callback", (error, results) => {
if (error)
console.error(error);
else {
const data = JSON.parse(results.text).results[0];
const contact = new Contact(this, data.dob, data.name, data.login.username, data.picture)
contact.addTag('random-user');
this.contacts.push(contact);
this.pendingRequestCount--;
}
}));
}
async
actions 和runInAction
action
只影响当前运行的函数,不是当前调度(不是调用)的函数。也就是说,如果你有一个setTimeOut
,promise.then
或async
构造,在回调中有更多的状态被该改变,这些回调也应该被包含在action
中。这可以在上面的"createRandomContact-callback"
操作来演示。
如果你使用async/await
,这就非常棘手了,因为你不能只是在action
中单纯的包装异步函数体了。在这种情况下,runInAction
就可以派上用场了,在你打算更新状态的地方使用它就可以了。(但是不要在await
中调用这些区块)
举例:
@action /*optional*/ updateDocument = async () => {
const data = await fetchDataFromUrl();
/* required in strict mode to be allowed to update state: */
runInAction("update state after fetching data", () => {
this.data.replace(data);
this.isSaving = true;
})
}
runInAction
的另外一种用法是: runInAction(name?, fn, scope?)