错误:[mobx-state-tree]无法解析引用XXX以键入“用户”

时间:2018-11-25 03:36:47

标签: javascript reactjs mobx mobx-state-tree

上下文

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

然后将这两个API的响应作为快照应用到同一树中的两个兄弟节点。项目模型的所有者字段是指用户模型。

我的问题是,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示例

GET https://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"
  },
  {
    ...
  },
  ...
]

GET https://service.com/api/workmanagement/projects?minStartDate=&maxStartDate=2018-11-24&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",
  },
  {
    // ...
  },
  ...
]

2 个答案:

答案 0 :(得分:2)

您可以应用的一种解决方案是在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时都需要检查它是否存在。

答案 1 :(得分:0)

听起来好像您在创建项目模型后可能正在加载用户数据 这可能和使用最新参考一样容易。听起来,这意味着创建此模型后可能会创建的任何类型。

代替此 owner: types.maybeNull(types.reference(User))

尝试一下 owner: types.maybeNull(types.late(() => types.reference(User)))