Как обрабатывать несколько хранилищ одного типа в Flux / ReactJS?

Я новичок в Flux / React, и мне сложно понять некоторые фундаментальные архитектурные решения:

  1. Я знаю, что все магазины должны быть одиночными, но все ли они создаются при запуске приложения или время жизни магазина может быть меньше в зависимости от действий пользователя?
  2. Могу ли я иметь несколько экземпляров одного и того же типа магазина, каждый из которых инициализирован с разным контекстом?

К сожалению, все примеры, которые я видел, кажутся слишком упрощенными, чтобы ответить на эти вопросы. Начнем с примера чат-приложения Facebook. Есть несколько цепочек, каждая с сообщениями. MessageStore содержит все сообщения для всего приложения, а метод getAllForThread (id) возвращает отфильтрованное подмножество сообщений. Когда сообщение поступает в ЛЮБОЙ поток, оно излучает уведомление об изменении, которое заставляет компонент реакции MessageSection повторно извлекать данные (независимо от того, какой поток просматривает пользователь). Это явно не масштабируется. Что, если бы у нас было 10 000 цепочек с большим количеством сообщений в каждой? Вот как я решил решить проблему:

  1. Каждое хранилище сообщений инициализируется идентификатором потока.
  2. Создайте одноэлементный MessageStoreFactory, который создает хранилища сообщений и управляет ими.
  3. Когда пользователь нажимает на поток, вместо того, чтобы компонент React подписался на глобальное хранилище сообщений, он запрашивает у MessageStoreFactory хранилище сообщений для этого конкретного потока.
  4. Если фабрика уже имеет хранилище сообщений для этого потока, она его возвращает. В противном случае он создает его, запускает асинхронную задачу, чтобы получить для него исходные данные, и возвращает их.
  5. Когда компонент React отключается (допустим, пользователь уходит от него), он уведомляет Factory о том, что с Store все сделано. Использование подсчета ссылок или какой-либо другой логики кеширования позволит Factory удалить неиспользуемые хранилища.

Насколько я далек от базы с таким подходом? Есть ли более простой подход, который все еще масштабируется?


person Brent Traut    schedule 14.05.2015    source источник
comment
Это явно не масштабируется. - Я был бы осторожен, чтобы не делать предположений о том, как магазины и компоненты будут вести себя в масштабе. Различия в React минимизируют операции DOM, а componemtShouldUpdate может перехватывать вещи до процесса рендеринга. Вы можете быть умным в том, что запрашивает ваш сборщик данных обновлений (возможно, запросите самые последние изменения, начиная с messageId # 16456 вместо getTheMessages).   -  person ottonomy    schedule 15.05.2015


Ответы (1)


Кажется, проще сделать умнее получение данных в зависимости от темы, которую просматривает пользователь. Могу я увидеть пример этого фейсбука в каком-нибудь блоге или презентации?

person Liubomyr Mykhalchenko    schedule 15.05.2015
comment
Обновил свой вопрос ссылкой. И снова здесь. - person Brent Traut; 15.05.2015
comment
Получение данных здесь не обязательно. Если MessageStore хранит все сообщения для каждого потока, он будет создавать событие изменения каждый раз, когда приходит какое-либо сообщение. Это сделает MessageStore невероятно шумным. Даже если выборка будет более оптимизирована, это все равно приведет к тому, что многие компоненты реакции будут обрабатывать эти события, когда они на самом деле не заинтересованы. Эта часть, кажется, не масштабируется. - person Brent Traut; 18.05.2015
comment
вам может потребоваться реализовать метод shouldComponentUpdate для предотвращения повторного рендеринга. Поскольку этот метод будет вызываться очень часто, он должен быть быстрым. Но вы можете использовать неизменяемые структуры данных (facebook.github.io/immutable-js) - person Liubomyr Mykhalchenko; 18.05.2015
comment
Но вы можете использовать неизменяемые структуры данных. Это сделает метод shouldComponentUpdate действительно простым и быстрым. facebook.github.io/react/docs/advanced-performance.html - person Liubomyr Mykhalchenko; 18.05.2015
comment
Я собираюсь отметить этот ответ как правильный, но больше из-за вашего предложения использовать immutable-js, чем из-за вашего фактического ответа. Мы все еще беспокоимся о масштабируемости, поэтому планируем рассмотреть подходы, которые включают очистку кешей данных хранилища и интеллектуальную выборку. Я уверен, что immutable-js сыграет важную роль в окончательном решении. - person Brent Traut; 20.05.2015
comment
@ Любко Ерунда. shouldComponentUpdate все равно будет вызываться для каждого компонента, который подписывается на хранилище. Это недопустимо. - person Szczepan Hołyszewski; 24.06.2016
comment
@ SzczepanHołyszewski Я не говорил, что shouldComponentUpdate не будет вызываться ... Я сказал, что он будет вызываться часто, поэтому он должен быть быстрым. Неприемлемым было бы вызывать render при каждом обновлении, а не shouldComponentUpdate. - person Liubomyr Mykhalchenko; 29.06.2016
comment
Вызов функции N-1 раз только для того, чтобы определить, что мы не должны ничего делать, и только один раз, чтобы определить, что мы должны что-то делать, является абсолютно неприемлемым с точки зрения качества программного обеспечения. Это просто мерзко на уровне пузырьков. Информация о том, какой единственный экземпляр следует обновить, доступна, когда мы отправляем изменение в магазин, а затем самоуверенная структура вынуждает нас проиграть эту информацию, а затем повторно вычислять ее за O (n) раз каждый раз. Это безумие. - person Szczepan Hołyszewski; 29.06.2016