Redux商店中的巨大物件
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redux商店中的巨大物件相关的知识,希望对你有一定的参考价值。
理想情况下,我们会在Redux中放入可能非常非常大(100k +行)的db查询的结果。
将结果放在redux中看起来有些过分,是否有一种干净的方法可以在redux存储中放置一种哈希或时间戳,并且能够在我的React组件中获取实际数据?
在Java中,我们可以以某种方式覆盖equals和hash,因此它不会做得非常平等,使得它更快。
默认情况下,Redux不使用深度比较。 https://redux.js.org/faq/immutable-data#redux-shallow-checking-requires-immutability
在该页面上有相当多的信息,但有点蒸馏 - Redux仅检查对象引用是否已更改。
没有看到任何代码,很难说出具体问题是什么。有可能你以某种方式将你的对象放在树上太高,而Redux正在遍历你巨大物体的第一层上的键。如果是这种情况,只需将对象包装在Redux状态可能会有所帮助。
{
huge: myHugeObject,
}
但实际上,这更像是一个绑匪。如果Redux正在遍历您的对象,那么您可能还没有正确使用它。
代码示例确实有助于诊断问题。
这将是我对最终表现的建议。请记住,我自己没有对此进行测试,但如果我正确理解您的问题,那么我认为没有理由说它不起作用。
您需要存储100K行数据,理想情况下,您需要将此数据保留在客户端。这里最好的解决方案是使用IndexedDB,因为您可以像数据库一样进行读写,同时还有足够的存储空间。像Soleil推荐的那样,我建议你使用dexie
与IndexedDB进行交互。你不需要它,但你肯定应该拥有它,因为它会给你带来很大的灵活性。
您还需要能够区分这些更改,如果不将工作推送到另一个线程上,那就不容易了。所以,建议如下:
async function seedData() {
// serialize your data, hopefully have unqiue id field on each row
const hundredK = toJSON(await fetch(source));
// IndexedDB doesn't have tremendous write speed, so it may be better to chunk your rows into
// 10k intervals for seem to perform the best but vary based on PC / browser implementation
const db = new Dexie("myDataSource");
// set version of Indexed to use (1 is preferred for best compatibility)
// and set the indexes
db.version(1).stores({
animals: 'id,type'
});
let mice = [];
for (let i = 0; i < hundredK.length; i++) {
mice.push({
id: i,
species: hundredK[i].species,
type: hundredK[i][0].type,
facts: {
someText: "this could come from hundredK, but I'll hardcode it",
someNumber: i
}
});
}
}
所以现在数据在IndexedDB中,你可以随时查询它。现在,您需要一种方法将性能较重的部件推送到另一个线程。幸运的是有redux-worker
import reducer from './reducers';
import task from './task';
import { createWorker } from 'redux-worker';
let worker = createWorker();
worker.registerReducer(reducer);
worker.registerTask('DIFF_IT', function (a) {
// do your diffing and expensive functions
task(a);
});
让你的工人生效
...
import { applyWorker } from 'redux-worker';
// you can't have any external dependencies for your worker, so bundle them or find a way to inline them
const worker = new Worker('./script.js') // alternatively inline an async function it with `greenlet-with-edge`
const enhancer = compose(applyMiddleware(thunk, logger), applyWorker(worker));
const store = createStore(rootReducer, {}, enhancer);
将您的数据库传递到您的组件,并挂钩更新。应用你的行动
// all in dexie docs
this.props.db.animals.hook('updating', (modifications, key, obj, tran) => {
if ("species" in modifications) {
this.props.actions.task(modifications.species, key, obj, tran);
}
})
您的主要关注点似乎是性能,尽管我会考虑评论中提到的建议,即:使用较小的有效负载,您需要将大量数据渲染到反应组件中,并且您需要它具有高性能,要实现这一点,你需要使用一个窗口组件,这将只渲染可见的行,并按需渲染其他所有内容,使渲染真正长的数据集真正高效,查看https://bvaughn.github.io/react-virtualized/并将数据传递给组件
以上是关于Redux商店中的巨大物件的主要内容,如果未能解决你的问题,请参考以下文章
如何纠正 Redux 商店中的 React-Redux-Firebase 错误
Reactjs:直接 Firebase 连接与 Firebase Redux 商店