MobX 操作是否允许显示确认对话框或导航到新屏幕?更一般地说,动作可以触及 ui 吗?

Are MobX actions allowed to show a confirm dialog, or navigate to a new screen? More generally, can actions touch ui?

我正在 大规模 应用程序中重构 MobX。因为它很大,所以让代码干净很重要。

有一个 action 执行以下操作(简化):

@action myAction() {
  var data = await api.getSomeDataFromServer();
  
  if (data.warnUser) {
    var userAgrees = await showConfirmDialog('Hey, are you really sure?'); // #1
    if (!userAgrees) return;
  }

  someOperations(data);

  Navigator.push('/another_page'); // #2
}

担心#1#2好不好。原因是,恕我直言,mobx 有一个 UI - action - state 三元组(如下图 mobx 书所示)。因此,Actions 应该直接修改 State 而不是 UI。但是在#1中,Action直接显示了一个对话框——也就是UI;在 #2 中,Action 直接导航到另一个页面 - 这也是 UI 相关的。

简而言之,MobX 的 action 可以直接“触摸”并操纵 ui 吗?

我对此进行了一些搜索,现在很困惑。感谢您的任何建议!

备注:我把它标记为Flutter和JavaScript,因为我确实在使用Flutter,但这个问题也适用于MobX的JS版本。

备注:以下是mobx书中的图表。

Mobx 的主要优点之一是使状态和 UI 完全分离。通过将状态与 UI 解耦,您的测试将更容易编写。您发布的示例很难测试。

我有一些项目,我会编写完整的应用程序业务逻辑,而根本不需要在 UI 上工作,然后我只需将状态和 state-changing 方法挂接到 UI.

此外,由于 Mobx 通过将 UI 与状态管理解耦来与 flutter 和 Javascript 一起工作,您可以将完整的业务逻辑移植到 Javascript,反之亦然。 因此总而言之,您的代码有效,但它不是 Mobx 方式 :)

例如,您可以mobx reaction对状态变化作出反应

@action myAction() {
  // if myAction is a method on JS class
  this.data = await api.getSomeDataFromServer();
}

然后在你的某处UI代码

reaction(
    () => myClassInstance.data, // when data changes
    data => { //<- run this function
  
     if (data.warnUser) {
       var userAgrees = await showConfirmDialog(); // #1
       if (!userAgrees) return;
     }

    someOperations(data);

    Navigator.push('/another_page'); // #2
    }
)

希望对您有所帮助