Mobx状态树是否会导致“竞争条件”/仅适用于setTimeout?

时间:2017-10-02 16:58:28

标签: javascript reactjs settimeout mobx

使用 mobx-state-tree 。我有ListStore,其中包含此操作:

 remove: process(function* remove(id) {
    try {
      self.markBeingRemoved(id); // set flag in store
      const element = yield getEnv(self).resource.remove(id); // async call
      self.removeFromList(element.id); // see below
      showSuccessNotification(); // some jQuery based notification library
    } catch (err) {
      showServerError();
    } finally {
      self.markBeingRemoved(null);
    }
  })

现在 removeFromList 只是这样做:

 const indexToRemove = self.list.findIndex(e => e.id === elementId);
    if (indexToRemove >= 0) {
      self.list.splice(indexToRemove, 1);
    }

现在我有一个使用该列表的React组件。注入类似于@inject('ListStore')。然后我将它作为道具传递给子组件。使用它的子组件都是mobx - observer s。

我得到了这个模糊的错误,Google对此一无所知:

mobx-state-tree.module.js?9486:50 Uncaught Error: [mobx-state-tree] 
This object has died and is no longer part of a state tree. 
It cannot be used anymore. 
The object (of type 'Template') used to live at '/list/1'. It is 
possible to access the last snapshot of this object using 
'getSnapshot', or to create a fresh copy using 'clone'. If you want to 
remove an object from the tree without killing it, use 'detach' 
instead.

at fail (webpack-internal:///467:92:11)
at Object.get (webpack-internal:///467:1409:17)
at Object.get [as id] (webpack-internal:///33:1682:28)
at dehydrate
at dehydrate (chrome-
extension://fmkadmapgofadopljbjfkapdkoienihi/build/backend.js:8154:24)
at dehydrate (chrome-
extension://fmkadmapgofadopljbjfkapdkoienihi/build/backend.js:8154:24)
at chrome-
extension://fmkadmapgofadopljbjfkapdkoienihi/build/backend.js:7285:20
at Array.map (native)
at Bridge.flushBufferSlice (chrome-
extension://fmkadmapgofadopljbjfkapdkoienihi/build/backend.js:7280:33)
at Bridge.flushBufferWhileIdle (chrome-
extension://fmkadmapgofadopljbjfkapdkoienihi/build/backend.js:7268:15)
fail @ mobx-state-tree.module.js?9486:50
get @ mobx-state-tree.module.js?9486:1367
get @ mobx.module.js?cbdf:1638
dehydrate @ backend.js:8154
dehydrate @ backend.js:8154
dehydrate @ backend.js:8154
    (anonymous) @ backend.js:72
flushBufferSlice @ backend.js:7280
flushBufferWhileIdle @ backend.js:726

现在出现了一个有趣的部分:如果我将 removeFromList 的调用放入setTimeout(..., 1000)就可以了!

为什么?

1 个答案:

答案 0 :(得分:1)

错误由反应开发人员工具触发。

他们在记忆中抓住一个死亡的物体,这就是他们投掷的原因。在没有devtools的生产中,他们不会触发这个错误。