Igo*_*nko 5 javascript reactjs mobx mobx-state-tree
我有一个由mobx-state-tree(MST)支持的React应用程序。其中一个页面进行两个并行的 API调用,以获取的列表Projects和系统的列表Users。
然后,将这两个API的响应作为快照应用到同一树中的两个兄弟节点。项目模型的所有者字段是指用户模型。
我的问题是,GET项目API调用通常比GET Users API调用更早完成。经典的“比赛条件”。因此,当MST尝试取消引用所有者值时,具有此类标识符的用户在树中不可用,并且出现如下运行时错误:
错误:[mobx-状态树]无法解析引用'dtGNbVdNOQIAX0OMGaH2r2oSEf2cMSk9AJzPAf4n7kA'以键入“用户”(来自节点:/ projectListStore / projects / 0 / owner)
如何解决该错误?
请注意,进行API调用相互依赖(await或users.load().then(users => { projects.load(); })不是我们项目的选择。
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,
})
// ...
Run Code Online (Sandbox Code Playgroud)
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"
},
{
...
},
...
]
Run Code Online (Sandbox Code Playgroud)
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",
},
{
// ...
},
...
]
Run Code Online (Sandbox Code Playgroud)
您可以应用的一种解决方案是在ProjectModel模型中将所有者定义为字符串
owner: types.maybeNull(types.string),
Run Code Online (Sandbox Code Playgroud)
然后在模型上定义一个计算属性,它将作为对象检索所有者
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)
}
}))
Run Code Online (Sandbox Code Playgroud)
您可以像这样使用它project1.ownerObject ? project1.ownerObject.firstName : ''
缺点是ownerObject您在使用它时总是需要检查是否存在。
小智 4
听起来您可能会在创建项目模型后加载用户数据,这可能就像使用后期引用一样简单。顾名思义,这适用于创建此模型后可能创建的任何类型。
而不是这个
owner: types.maybeNull(types.reference(User))
尝试这个
owner: types.maybeNull(types.late(() => types.reference(User)))
| 归档时间: |
|
| 查看次数: |
813 次 |
| 最近记录: |