【问题标题】:Error: [mobx-state-tree] Failed to resolve reference XXX to type 'User'错误:[mobx-state-tree] 无法解析引用 XXX 以键入“用户”
【发布时间】:2018-11-25 03:36:47
【问题描述】:

上下文

我有一个由 mobx-state-tree (MST) 支持的 React 应用程序。其中一个页面进行两个并行 API 调用以获取Projects 列表和系统Users 列表。

这两个 API 的响应随后会作为快照应用到同一棵树中的两个兄弟节点。 Project 模型的 owner 字段引用了 User 模型。

我的问题是 GET 项目 API 调用通常比 GET Users API 调用更早完成。经典的“比赛条件”。因此,当 MST 尝试取消引用所有者值时,具有此类标识符的用户在树中不可用,并且我收到如下运行时错误:

错误:[mobx-state-tree] 无法解析引用“dtGNbVdNOQIAX0OMGaH2r2oSEf2cMSk9AJzPAf4n7kA”以键入“用户”(来自节点:/projectListStore/projects/0/owner)

问题

如何解决该错误?

请注意让 API 调用相互依赖(awaitusers.load().then(users => { projects.load(); })不是我们项目的选项。

MST 模型

export const ProjectModel = types
  .model('Project', {
    projectId: types.optional(types.identifierNumber, 0),
    title: '',
    descriptionStatus: '',
    projectStatus: '',
    startDate: CustomDate,
    endDate: CustomDate,
    owner: types.maybeNull(types.reference(User)), // -----
  })                                                        \ 
  // ...                                                     |
                                                             |
export const User = types                                    |
  .model('User', {                                          /
    userId: types.identifier,                      // <<<--
    userName: '',
    firstName: '',
    lastName: '',
    email: '',
    lastVisited: CustomDate,
  })
  // ...

API 示例

GEThttps://service.com/api/users

[
  {
    "userId": "g-gqpB1EbTi9XGZOf3IkBpxSjpAHM8fpkeL4YZslEL8",
    "userName": "john.doe@service.com",
    "firstName": "John",
    "lastName": "Doe",
    "email": "john.doe@service.com",
    "lastVisited": "2018-01-18T17:32:48.947"
  },
  {
    ...
  },
  ...
]

GEThttps://service.com/api/workmanagement/projects?minStartDate=&amp;maxStartDate=2018-11-24&amp;status=Active

[
  {
    "projectId": 1,
    "title": "Project Title",
    "description": "Praesent luctus vitae nunc sed condimentum. Duis maximus arcu tortor, vitae placerat enim ultrices sed. Etiam scelerisque gravida justo, vitae venenatis dui pellentesque eu.",
    "projectStatus": "active",
    "startDate": "2018-08-20T00:00:00",
    "endDate": "2019-07-01T00:00:00",
    "owner": "g-gqpB1EbTi9XGZOf3IkBpxSjpAHM8fpkeL4YZslEL8",
  },
  {
    // ...
  },
  ...
]

【问题讨论】:

    标签: javascript reactjs mobx mobx-state-tree


    【解决方案1】:

    您可以应用的一种解决方案是在 ProjectModel 模型中将所有者定义为字符串

    owner: types.maybeNull(types.string), 
    

    然后在模型上定义一个计算属性,它将所有者作为对象检索

    export const ProjectModel = types
      .model('Project', {
        projectId: types.optional(types.identifierNumber, 0),
        title: '',
        descriptionStatus: '',
        projectStatus: '',
        startDate: CustomDate,
        endDate: CustomDate,
        owner: types.maybeNull(types.reference(User)), // -----
      }).views(self => ({
      get ownerObject(): undefined | Instance<typeof User> {
        // get the user manually from the tree
        const root = getRoot(self)
    
        return resolveIdentifier(User.Type, root, self.owner)
      }
    }))
    

    你可以像这样使用它project1.ownerObject ? project1.ownerObject.firstName : '' 缺点是您在使用时始终需要检查ownerObject 是否存在。

    【讨论】:

    • MST 引用最近让我失望了太多,我真的很喜欢计算属性的建议。谢谢!
    【解决方案2】:

    听起来您可能会在创建项目模型后加载用户数据 这可能就像使用后期参考一样容易。听起来,这适用于在创建此模型后可能创建的任何类型。

    而不是这个 owner: types.maybeNull(types.reference(User))

    试试这个 owner: types.maybeNull(types.late(() =&gt; types.reference(User)))

    【讨论】:

      猜你喜欢
      • 2020-11-14
      • 2021-12-24
      • 2019-11-26
      • 2011-05-18
      • 2021-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多