javascript - 替换可观察数据时的 MobX 性能

标签 javascript reactjs mobx

当我从套接字获得新的转储时,我需要替换我的可观察对象中的数据:

class Store {
    @observable data = { foo: 'bar' }
    replaceFromDump(newData) {
        this.data = newData
    }
}
const store = new Store()
store.replaceFromDump({ foo: 'bar' })

// { foo: 'bar' } can be a huge amount of JSON

但是,我注意到当数据对象扩展时性能会受到影响,这可能是因为即使某些属性/值相同,MobX 也会在任何地方触发 react 。

有没有更“聪明”的方法? - 我认为 f.ex 只替换对象受影响的部分会比替换整个可观察对象更好?

我在这里做了一个小演示来解释我的意思: https://jsfiddle.net/yqqxokme/ 。 替换对象会引起新的 react ,即使数据完全相同(预期)。但我确信有一种方法可以只改变数据对象的受影响部分,就像在 merge() 中一样。功能。

最佳答案

所以这里有一些事情和案例。我已将转储功能更改为以下以模拟更改

variations = [
  {foo: 'bar'},
  {foo: 'bar'},
  {foo: 'bar2' },
  {foo: 'bar2' },
  {foo: 'bar2', bar: {name: "zoo"} },
  {foo: 'bar2', bar: {name: "zoo"} },
  {foo: 'bar2', bar: {name: "zoo2"} },
  {foo: 'bar2', bar: {name: "zoo2"} },
  {foo: 'barnew', bar: {name: "zoo2", new: "yes"} },
  {foo: 'barnew', bar: {name: "zoo2", new: "no"} },
  {foo: 'barnew', bar: {name: "zoo2", new: "no"} }
]

i=0;

dump = () => {
  i++;
  i = i%variations.length;
  console.log("Changing data to ", variations[i]);
    store.replaceFromDump(variations[i])
}

使用 extendObservable

现在如果你使用下面的代码

replaceFromDump(newData) {
  extendObservable(this.data, newData)
}

并通过转储循环运行它,输出如下

Output 1

bar 的事件不会开始引发,直到您对 foo 进行更改,这发生在下面的更改中

{foo: 'barnew', bar: {name: "zoo2", new: "yes"} },

结果:新的key只能被observed existing observable keys change

使用 map

这里我们修改如下代码

  @observable data = map({
    foo: 'bar'
  })

replaceFromDump(newData) {
  this.data.merge(newData)
}

Output 2

结果:数据仅合并,不会被删除。您还将获得重复事件,因为它是仅合并选项

使用对象差异

你可以使用像下面这样的对象差异库

https://github.com/flitbit/diff

您可以像下面这样更新代码

  @observable data = {
    foo: 'bar'
  }

replaceFromDump(newData) {
    if (diff(mobx.toJSON(this.data), newData)){
        this.data = newData;
    } 
}

Output 3

结果:事件仅在数据更改时发生,而不是在重新分配给同一对象时发生

使用差异和应用差异

使用我们之前提供的相同库,我们可以只应用需要的更改

如果我们像下面这样修改代码

replaceFromDump(newData) {
    observableDiff(toJSON(this.data), newData, d => {
          applyChange(this.data, newData, d);
    })
  } 

如果运行上面的代码,我们得到以下输出

Output 4

结果:仅观察到初始键集的更改,前提是您不要删除中间键中的那些

它还为您提供以下格式的差异

{"kind":"E","path":["foo"],"lhs":"bar2","rhs":"barnew"}
{"kind":"N","path":["bar","new"],"rhs":"yes"}

这意味着您可以根据需要更好地控制基于字段名称的事物

下面是我使用的 fiddle ,大部分代码都有注释,但如果您需要查看下面的导入,请使用

https://jsfiddle.net/tarunlalwani/fztkezab/1/

关于javascript - 替换可观察数据时的 MobX 性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50000464/

相关文章:

javascript - 无法弄清楚如何使用 {this.props.etc} 尤其是 React.js 中的 map

javascript - 使用 MobX 存储循环引用进行设置测试

javascript - 检查 localStorage 是否可用

javascript - 如何获取对象数组而不是数组数组

javascript - 如何记录仅具有原始值的对象?

javascript - 如何将提交的表单数据发送到本地服务器

javascript - jquery第n个选择器,交替颜色但不使用奇数和偶数选择器

javascript - 迁移到 meteor / react

reactjs - Mobx-state-tree 在树内使用 mobx react - 好的还是坏的做法?

node.js - 在服务器中使用 mobx-model