首页 > 解决方案 > 在 mobx-state-tree 中异步加载引用的数据

问题描述

我查看了mobx -state-tree 文档甚至测试文件https://github.com/mobxjs/mobx-state-tree/blob/master/packages/mobx-state-tree/tests/core/reference- custom.test.ts#L148 找出如何从异步源填充参考节点。例如,加载了 user1 并引用了 user2,但 user2 不在树中,所以去获取 user2 并加载它。在过去,我让所有用户都在早期加载,所以 types.late() 工作得很好。但是我已经在加载开始时停止加载所有用户,而是只想加载被引用的用户数据。

这是一个示例片段。我实际上并没有让这个示例在沙箱中工作,因为我正在向你们那里的好人寻求指导帮助,了解在何处以及如何异步获取丢失节点的逻辑。您会注意到在创建商店时加载的两个用户引用了尚未加载的第三个用户。当 MST 使用前两个用户填充树并遇到对未加载用户 ID 的引用时,我们如何让它获取用户然后将其添加到用户映射中?

export const User = types
      .model("User", {
        id: types.identifier,
        name: types.string,
        friends: types.array(types.late(types.reference(User)))
      })
      .preProcessSnapshot(snapshot => {
        if (snapshot){
            return({
              id: snapshot.id,
              name: snapshot.name,
              friends: snapshot.friends
            })
        }
      })

    export const UserStore = types
      .model("UserStore", {
        users: types.map(User),
      })
      .actions( self => ({
        fetchUser: flow(function* (userId) {
          let returnThis
          try {
            returnThis = yield ajaxFetchUser(userId) 
            self.users.put(returnThis)
          } catch (error) {
            console.log(error)
          }
          return self.users.get(returnThis.id)
        })
      }))

    UserStore.create({
      users:[{
        id: 1,
        name: "Justin",
        friends: ["2","3"]
      },{
        id: 2,
        name: "Jack",
        friends: ["1","3"]
      }]
    })

    const ajaxFetchUser = (userId) => {
      // pretend that userId is 3
      setTimeout(()=>{
        return {
          id:3,
          name: "John",
          friends: ["1","2"]
        }
      }, 3000)
    }

当然,我使用的脚本比这段代码复杂得多,具有适当的 map.put 和 map.get 操作。

如果有人能对这个主题有所了解,我将不胜感激。

标签: mobxmobx-state-tree

解决方案


您可以尝试拦截试图访问特定属性(在您的案例参考中)的人,方法是将其转换为 getter(基本上是创建一个视图)并从那里安排一个操作(数据获取)。我知道看起来你在那里违反了某些东西(你确实是),但这就是你所追求的。我认为这就是 MobX 在幕后的运作方式,也许它违反最佳实践的事实促使其作者转而使用代理。嗯...您可能也想尝试代理


推荐阅读