在mobx状态树中异步加载引用的数据

时间:2019-12-03 15:29:12

标签: mobx 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操作。

如果有人可以在这个问题上有所作为,我非常有义务。

1 个答案:

答案 0 :(得分:0)

您可以尝试通过将某人变成一个getter(基本上是一个视图)并从那里安排一个动作(获取数据)来拦截试图访问该特定属性的人(以您的情况为参考)。我知道您似乎在侵犯那里的东西(而且您确实在),但这就是您所追求的。我认为无论如何都是MobX在后台运行的方式,也许事实是它违反了最佳实践,这促使它的作者转而使用代理。嗯...您可能也想尝试Proxy