Подтвердить что ты не робот

Где длительные процессы живут в приложении React + Redux?

Где долгие процессы "живут" в приложении "реакция + сокращение"?

Для простого примера рассмотрим класс, который отправляет и принимает сообщения через веб-узел:

class WebsocketStreamer {
  sendMessage(message) {
    this.socket.send(…);
  }

  onMessageReceive(event) {
    this.dispatch({
        type: "STREAMER_RECV",
        message: event.data,
    })
  }
}

Как управлять жизненным циклом этого класса?

Мой первый инстинкт - сохранить его на store:

var stores = {
  streamer: function(state={}, action) {
    if (action.type == "@@INIT")
      return { streamer: new WebsocketStreamer() }
    if (action.type == "STREAMER_SEND")
      state.streamer.sendMessage(action.message)
    return state;
  }
}

Но, не считая немного странного, для WebsocketStreamer нет доступа к функции dispatch(), и она прерывает горячую перезагрузку.

Еще одно потенциальное решение - сохранить его где-то в глобальном масштабе:

const streamer = new WebsocketStreamer();

Но это имеет очевидные последствия для тестируемости и слишком быстро перегружает.

Итак, где должен длительный процесс жить в приложении реакции + сокращение?

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

4b9b3361

Ответ 1

По моему опыту, есть два варианта. Во-первых, вы можете передать хранилище на любой код, не относящийся к Redux, и отсылать его отсюда. Я сделал это с подключением сокетов, и все было в порядке. Во-вторых, если вам нужно сокет или что-то другое, чтобы изменить с помощью действий redux, похоже, хорошая идея установить соединение и управлять им в пользовательском промежуточном программном обеспечении. У вас будет доступ к API-хранилищу, а также будет сообщен обо всех действиях диспетчеризации, поэтому вы можете сделать все, что вам нужно.

Ответ 2

Я делаю что-то похожее с websockets. В моем случае я просто обертываю клиент websocket в компоненте React, который отображает нуль и вставляет его как можно ближе к корню.

<App>
    <WebSocketClientThingy handlers={configuredHandlers}/>
    ....
</App>

Вот краткий пример. Это довольно наивно, но делайте что-нибудь.

https://github.com/trbngr/react-example-pusher

Быстрое примечание: Веб-камера не живет в магазине. Он просто там и публикует действия.

EDIT: Я решил исследовать установку клиента (долгоживущего объекта) в глобальное состояние. Я должен сказать, что я поклонник этого подхода.

https://github.com/trbngr/react-example-pusher/tree/client_as_state

Ответ 3

Я открываю исходный код для отслеживания проблем с долгосрочными операциями, используя React/Redux/Node, весь задействованный код, но с открытым исходным кодом и MIT. Иногда мне нужно вытащить или подтолкнуть репо, и в зависимости от соединения это может занять много времени, вот когда наступает следующая длительная операция.

В целом, ключевые моменты подхода:

  • Резервное хранилище с активными операциями и его статусом.
  • Резервный магазин с событиями операций
  • Инициализируйте хранилище операций со всеми текущими операциями на странице инициализация
  • Используйте сервер событий http для обновления состояния операции, данных, ошибок, завершений, хода выполнения и т.д.
  • Подключите компоненты, такие как кнопки, к текущему состоянию работы.
  • Для каждого компонента ведите список задействованных операций и параметров, если операция и параметр совпадают... измените состояние кнопки на загрузку/выполнено/и т.д.
  • Измените состояние хранилища операций с помощью обновления событий или результатов запроса (я использую GraphQL, и все мутации возвращают тип "Операция")

Вовлеченные репозитории:

Вот как это выглядит: https://user-images.githubusercontent.com/36018976/60389724-4e0aa280-9ac7-11e9-9129-b8e31b455c50.gif

Сохранение состояния таким образом также поможет вам:

  • Состояние текущих операций сохраняется, даже если окно обновляется
  • Если вы открываете два или более окон и выполняете операции в одном окне, состояние выполняемых операций и пользовательский интерфейс для всех окон также синхронизируются.

Я надеюсь, что подход или код поможет.