machinelearningmastery.ru

Машинное обучение, нейронные сети, искусственный интеллект
Header decor

Home

Совместное использование состояния между вкладками браузера с Redux.

Дата публикации Oct 3, 2019

Виадук Мийо, Франция - изображение поЛилис помощьюThingLink

Введение

Веб-приложения с каждым днем ​​становятся все сложнее, причем не только они становятся больше, но и в некоторых случаях пользователям приходится использовать несколько экземпляров одного и того же приложения на разных вкладках. Создание приложений такого типа - непростая задача из-за отсутствия библиотек и документации. Учитывая, что некоторые библиотеки устарели или не имеют многих реализованных функций, вам, разработчику, приходится иметь дело почти со всем; Вы можете согласиться с этими ограничениями сторонней библиотеки или создать собственное решение, которое, вероятно, может стоить вам больше времени и денег.

Есть лишь несколько вариантов, которые вы можете выбрать в зависимости от ваших предпочтений: LocalStorage, Web Workers, Web Sockets & IndexedDB. Мы не будем покрывать веб-сокеты, поскольку для этого вам нужен сервер, и мы стремимся к решению для клиента (браузера).

Например, если вы хотите использоватьlocalStorage, нет библиотек, которые бы помогли вам это сделать (по крайней мере, не все), к счастью, естьпараизСообщения в блогеэто может дать вам представление, но этого все еще недостаточно, по этой причине это может быть самым сложным способом реализации синхронизации состояний между вкладками. Вы также должны иметь в виду, что нет никакого способа обновить все состояние из Redux, вместо этого вы должны отправлять действия, но мы немного разберемся с этим. В этом конкретном случае мы попробуем два разных подхода, один из которых - без использования библиотек, и вы проведете процесс, который вам необходимо выполнить, чтобы обеспечить синхронизацию между таблицами. Второй вариант заключается в использовании библиотеки, которая поможет нам хранить все вStorage, но будет несколько вещей, которые должны быть реализованы.

Если вы хотите сделать снимок в Web Workers и отправлять сообщения между вкладками, чтобы синхронизировать их, используйтеперевождь состояния синхронизациино вы все равно должны реализовать несколько вещей. Есть третий вариант, и это использование IndexedDB, для такого случая самый простой способ сделать это с библиотекой, которая уже реализует синхронизацию, какперевождь-pouchdb,

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

Мы не будем покрывать:

  • Поддержка нескольких или разных браузеров / машин. Если вам нужна поддержка для этого, вы можете реализовать веб-сокеты, но большая часть информации, перечисленной здесь, все еще полезна для этого сценария.
  • Сохранение всего государства наStoreна "Нулевые библиотеки »реализация.
  • Загрузка начального состояния (после обновления / нового экземпляра) изStoreна "Нулевые библиотеки »Реализация.

Реализации

Мы будем использовать Reduxпример из репо Reduxочень известный,Список TodoMVCЭто уже созданное приложение React / Redux, которое сэкономит нам много времени и в то же время позволит нам сосредоточиться.

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

Мы будем использовать базуindex.jsиз репозитория для каждой реализации каждая реализация будет помечена как diff.

Это будет результатом, мы добьемся того же поведения с каждой реализацией:


Вариант № 1: локальное хранилище / хранилище сеансов

Вероятно, это может быть самым сложным способом реализации синхронизации между вкладками, потому что практически нет документации, которая поможет вам разобраться в деталях, которые необходимо учитывать при синхронизации состояния черезlocalStorageилиsessionStorage, В этом нет никакой серебряной пули, мы немного запачкаем руки, чтобы полностью поддержать синхронизацию с этим подходом.

Есть два пути: либо вообще не использовать библиотеки, либо создать собственное решение с нуля, либо использовать частичное решение, которое действительно позаботится о некоторых вещах для вас.

Следует иметь в виду, что все вlocalStorageилиsessionStorageдолжен быть сериализован, что означает, что есть вызовыJSON.stringifyа такжеJSON.parseделается.Эти две функции хорошо известны тем, что они дороги,

Нулевые библиотеки

Использование каких-либо библиотек для этого не является легкой задачей, отсутствие документации и списка реализуемых функций может быть огромным. Для того, чтобы обмениваться данными между двумя (или более) вкладками через локальное / сессионное хранилище, сохраните отправленные действия и прослушайтеstoreсобытие на другой вкладке Мы должны помнить, что мы также должны установить начальное состояние из «хранилища», иначе вкладки будут не синхронизированы, когда они вновь открываются или обновляются.

Прежде всего, мы собираемся создать Reduxmiddlewareхранить действия вlocalStorageи повторить их на другой стороне. Мы должны создать файл для написания промежуточного программного обеспечения:

middleware/storage.js

middleware/storage.js

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

Мы также должны слушатьstorageмероприятиена другой вкладке. для этого мы добавляем еще один файл,event listener,

utils/storage-listener.js

Слушатель анализирует объект, сохраненный вstorageи введя фактический магазин, мы можем использовать закрытие и использоватьstore.dispatchкаждый раз, когда событие срабатывает. Теперь промежуточное программное обеспечение должно быть включено в поток Redux, а слушатель должен быть подписан.indexфайл.

index.js

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

Плюсы:

  • Может быть поддержано и обновлено командой. Это означает, что вы можете построить его поверх него, если нужно, очень легко.

Минусы:

  • Должен поддерживаться командой. Если у вас нет бюджета или времени, это может быть действительно плохим выбором.
  • Для первоначальной конфигурации нужно написать много кода.
  • Обработка очень дорога из-за сериализации данных.
  • Нет доступной документации
  • Вы должны создать свою собственную поддержку для сторонних библиотечных структур (т.е. ImmutableJS).

Redux-упорствовать

Эта опция немного проще, чем предыдущая, потому что кода не так много, так какRedux-упорствоватьуже заботится обо всей сохраняемости состояния и обработке действий, мы просто должны определить начальный конфиг и затем добавить прослушиватель для репликации действий и«Увлажняет»магазин Redux.

Прежде чем мы начнем, мы должны установитьredux-persist:

$ yarn add redux-persist

Автор библиотеки также создал библиотеку под названиемredux-persist-crosstabчто в сочетании сredux-persist, дает нам все, что мы хотим из коробки, но больше не поддерживается, что означает, что последняя версияredux-persistне работает сredux-persist-crosstab,

Начнем с определения слушателя:

utils/reduxpersist-listener.js

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

Мы вводим две зависимости в функцию: первый параметр - это фактическое хранилище, чтобыstore.dispatch, как и в предыдущем примере, иredux-persistобъект конфигурации для получения сохраненного состояния. Затем возвращается асинхронное закрытие, чтобы мы могли подписаться на событие для выполнения извлечения состояния и повторной гидратации.

index.js

Это может выглядеть как много кода, но со всем этим мы уже покрыли начальное состояние, загружаемое изstorageЭто одна вещь, о которой меньше беспокоиться, и это в основном все объекты конфигурации.

Плюсы:

  • Исходное состояние загружается из сохраненного состояния из коробки.
  • Легко понять и управлять.

Минусы:

  • Слишком много настроек.
  • Не все функции поддерживаются с самого начала.
  • Требуется ремонтопригодность от команды.
  • Обработка очень дорога из-за сериализации данных.
  • Вы должны создать свою собственную поддержку для сторонних библиотечных структур (т.е. ImmutableJS).
  • Маленькая (почти нет) поддержка со стороны сообщества.

Вариант № 2: веб-работники

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

Мы собираемся использовать библиотеку для этого случая, простую, называемуюredux-state-sync, его вторая версия, которая реализуетBroadcastChannelпервый реализован через локальное хранилище

Redux-State-Sync 2.0

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

Прежде всего, мы должны установить библиотеку:

$ yarn add redux-state-sync

Использовать эту библиотеку очень просто, поэтому начнем с добавления конфигурации библиотеки, очень простой (она может быть настолько сложной, насколько вы захотите). На самом деле, мы будем использовать пустойconfig, как вы можете видеть в коде ниже. Вот как нашиindex.jsфайл будет в конечном итоге искать.

index.js

Код выше очень интуитивно понятен, с именами функций очень легко понять поток. Как видите, проще, чем два предыдущих варианта сstorage`Storage`.

Мы должны сделать еще одну вещь для работы приложения. Мы должны обернуть весьreducerобъект с функцией из библиотеки под названиемwithReduxStateSyncтак что приложение может синхронизировать состояние, поэтому мы будем обновлятьindex.jsфайл внутриreducersпапки. Вот как это выглядит после наших изменений:

reducers/index.js

Плюсы:

  • Минимальная конфигурация, необходимая для начала.
  • Загрузить предыдущее состояние при перезагрузке без дополнительной настройки, из коробки.
  • Все функции нужны без написания ни единой строчки кода, просто конфиги.

Минусы:

  • BroadcastChannel поддерживается не каждым браузером.

Вариант № 3: IndexedDB

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

Redux-PouchDB

Нам нужны две библиотеки в этом случае, нам нужноофициальныйPouchDBбиблиотека плюс поддержкаRedux сredux-pouchdb,

$ yarn add pouchdb redux-pouchdb

Как и в предыдущем примере с WebWorkers, мы собираемся обернуть редукторы, чтобы иметь возможность их синхронизировать. Мы будем использоватьpersistentReducerфункция отredux-pouchdbбиблиотека, чтобы обернутьrootReducer:

reducers/index.js

Наконец, мы собираемся инициализировать базу данных PouchDB и подключитьredux-pouchbпромежуточное программное обеспечение вReduxтечь:

index.js

Плюсы:

  • Минимальная конфигурация, необходимая для начала.
  • Загрузить предыдущее состояние при перезагрузке без дополнительной настройки, из коробки.
  • Все функции нужны без написания ни единой строчки кода, просто конфиги.
  • IndexedDB поддерживается во всех браузерах.

Минусы:

  • PouchDB широко не используется в качестве WebWorkers и может создать высокую кривую обучения для разработчиков в команде.

Вывод

Три варианта очень полезны, хотя использование Web Workers может быть лучшим вариантом в большинстве случаев из-за широкого распространения сообщества JS, и без добавления множества зависимостей вы можете получить практически все функции, которые вам нужны. Используяstorageбезусловно, самый дорогой, потому что не только данные должны быть сериализуемыми, но и анализироваться в / из объектов JS с помощью JSONParseа такжеStringifyкоторыйодна из самых дорогих функций в JSиз-за его рекурсивной природы, хотя вы можете использоватьбыстро JSON-stringifyв качестве альтернативы в вашей собственной реализации или отправьте запрос на извлечение в любую сохраняющуюся библиотеку, которую вы используете (если они еще не используют ее) и одновременно поддерживают проекты с открытым исходным кодом!

При хранении данных вStorageилиIndexedDBявляется то, что естьмаксимальный предел пространствадля каждого из них и зависит от поставщиков браузеров и от того, загружается ли ваше приложение с мобильного или настольного браузера.

Оригинальная статья

Footer decor

© machinelearningmastery.ru | Ссылки на оригиналы и авторов сохранены. | map