Пакетные действия в redux-saga

Я прочитал на https://react-redux.js.org/api/batch что можно использовать batch ", чтобы гарантировать, что несколько действий, отправленных вне React, приводят только к одному обновлению рендеринга", как это (которое я использую в обработчике событий React, т.е.):

...
const submitData = event => {
    // ... some code before
    batch(() => {
        dispatch(first())
        dispatch(second())
    })
}
...

Но мой вопрос в том, как правильно batch действия в redux-saga, чтобы результат был один повторный рендеринг вместо нескольких при отправке нескольких действий из саги? Я попытался поместить несколько put в массив all, но не уверен, что он действительно группирует put:

yield all([
    put(addFirst({first: 1})),
    put(addAnother({second: 2)),
]);

Вышеупомянутый подход обусловлен тем, что я прочитал документацию на странице https://github.com/manaflair/redux-batch где автор написал: "Поскольку этот пакет был написан, redux-saga улучшилась, и использование all ([put (...), put (...)]], кажется, правильно объединяет два действия в одно событие подписки, что делает избыточность пакета redux-batch в этом сценарии. ", но в https://github.com/manaflair/redux-batch/issues/21 другой человек написал, что пакетирование обрабатывается React unstable_batchedUpdates API. Тем не менее redux-toolkit (который я использую) есть пример с redux-batch как store enhancer (https://github.com/reduxjs/redux-toolkit/blob/master/docs/api/configureStore.md).

Так что если кто знает правильный путь, поделитесь, пожалуйста, своими знаниями! С уважением

РЕДАКТИРОВАТЬ: Я использую batch в обработчиках событий React только для пакетной обработки нескольких действий. В redux-saga я хочу использовать пакет redux-batch.

Итак, правильный способ (при использовании redux-batch, который, по-видимому, нравится redux-toolkit, потому что пример) заключается в следующем:

import { reduxBatch }                            from '@manaflair/redux-batch';
import { put, takeEvery }                        from 'redux-saga/effects';
import createSagaMiddleware                      from 'redux-saga';
import { applyMiddleware, compose, createStore } from 'redux';

let sagaMiddleware = createSagaMiddleware();
let store = createStore(reducer, compose(reduxBatch, applyMiddleware(sagaMiddleware), reduxBatch));

sagaMiddleware.run(function* () {
  yield takeEvery(`*`, function* (action) {

    // Duplicate any event dispatched, and once again, store
    // listeners will only be fired after both actions have
    // been resolved/

    yield put([ action, action ]);

  });
});

Поэтому для yield put ([action, action]); иметь массив в put и отправлять несколько действий?


person user1665355    schedule 21.01.2020    source источник


Ответы (2)


Я сопровождаю Redux и являюсь автором Redux Toolkit.

На самом деле я только что написал в блоге сообщение под названием Сравнение методов пакетной обработки Redux, который охватывает различные формы пакетной обработки, доступные с действиями Redux.

Как я только что прокомментировал в этой redux-batch проблеме:

Использование unstable_batchedUpdates() в самом React-Redux только пытается минимизировать вложенные повторные отрисовки из одной отправки. Это не совпадает с целью этого проекта, который пытается разрешить отправку нескольких действий одновременно, одновременно уведомляя подписчиков магазина только один раз.

По вашему исходному вопросу, я не уверен, что вы можете правильно использовать batch() API React-Redux в сагах из-за необходимости yield put(). batch() API (который является просто реэкспортированным unstable_batchedUpdates() API React) полагается на отслеживание любых обновлений состояния React, которые ставятся в очередь во время одного тика цикла событий, и я подозреваю, что использование генераторов может не работать с этим. Чтобы убедиться, мне нужно увидеть примеры в действии.

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

person markerikson    schedule 21.01.2020
comment
Спасибо за ответ, пожалуйста, ознакомьтесь с моими изменениями, правильно ли использовать yield put ([action, action]), т.е. иметь массив с несколькими действиями? Tnx для redux-toolkit, спаситель для моего проекта redux! - person user1665355; 22.01.2020
comment
Да, хотя я сам серьезно не использовал redux-batch, насколько мне известно, он позволяет передавать массив действий в dispatch() и, следовательно, должен работать для put(). - person markerikson; 22.01.2020
comment
Спасибо, наверное, и за all([ put(...), put(...) ]), я думаю - person user1665355; 22.01.2020

Я думаю, вы можете просто put сделать это, согласно документации

yield put((dispatch) => {
  batch(() => {
    dispatch(action1);
    dispatch(action2);
  });
});
person wang chenyu    schedule 23.04.2021
comment
Не могли бы вы дать ссылку на документацию? - person user1665355; 23.04.2021
comment
batch - это действие, экспортированное из response-redux, а не из redux-saga, если это то, о чем вы спрашиваете - person wang chenyu; 04.05.2021
comment
хорошо, тогда это не то же самое. Вы это увидите, если прочтете ответ маркериксон. - person user1665355; 04.05.2021