Огромный объект в магазине Redux - PullRequest
0 голосов
/ 20 февраля 2019

В идеале мы бы поместили в Redux результат запроса к базе данных, который мог бы быть очень, очень большим (100 000+ строк).

Выглядит как излишнее прибавление результата к редуксу, есть ли чистый способпоставить хэш или временную метку в хранилище с избыточностью и иметь возможность получать фактические данные в моем компоненте React?

В Java мы могли бы как-то перезаписать equals и hash, чтобы не делать глубоких равных, делая это намного быстрее.

Ответы [ 3 ]

0 голосов
/ 07 марта 2019

Redux по умолчанию не не использует глубокое сравнение.https://redux.js.org/faq/immutable-data#redux-shallow-checking-requires-immutability

На этой странице довольно много информации, но она немного искажена - Redux только проверяет, изменилась ли ссылка на объект.

Трудно сказать, в чем заключается конкретная проблема.видя любой код.Вполне возможно, что вы каким-то образом помещаете свой объект слишком высоко в дерево, и Redux перебирает ключи на первом уровне вашего огромного объекта.Если это так, то может помочь простое оборачивание вашего объекта в состояние Redux.

{
   huge: myHugeObject,
}

Но на самом деле это скорее бандит.Если Redux обходит ваш объект, вы, вероятно, не совсем правильно его используете.

Пример кода действительно поможет диагностировать проблему.

0 голосов
/ 07 марта 2019

Это было бы моим предложением для максимальной производительности.Имейте в виду, я сам не проверял это, но если я правильно понимаю вашу проблему, то не вижу причин, по которым она не будет работать.

Вам нужно хранить 100К строк данных, и в идеале вам это нужноданные для сохранения на стороне клиента.Лучшее решение здесь - использовать 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);
  }
})
0 голосов
/ 06 марта 2019

Ваша главная проблема, похоже, связана с производительностью, хотя я бы остановился на предложениях, которые были упомянуты в комментариях, а именно: используйте меньшую полезную нагрузку, вам нужно преобразовать много данных в компонент реагирования, и вам это нужноБыть быстрым, для достижения этого вам нужно использовать оконный компонент, который будет рендерить только видимые строки, а все остальное отрисовывать по требованию, делая рендеринг действительно длинных наборов данных действительно быстрым, изучите https://bvaughn.github.io/react-virtualized/ и просто передайте данныек компоненту

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...