диспетчеризация действий во вложенных функциях в redux-саге - PullRequest
0 голосов
/ 28 января 2020

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

Basi c структура: Мое приложение настроено так, что для показа модального режима все, что вам нужно сделать, - это отправить действие с модальным телом в качестве полезной нагрузки для действия.

dispatch({type: SHOW_MODAL, payload: <MyModal />})

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

// mySaga.js

function* submitForm() {
  // show a modal
  // then show another modal
  // then submit the form
}

Каков наилучший способ сделать это? Для меня наиболее разумно использовать обещания.

// mySaga.js
function* submitForm() {
 yield call(() => {
   new Promise( resolve => {
     yield put({type: SHOW_MODAL, payload: <MyModal onClick={resolve} />})
   })
 })
 ...
 // add as many more modals as I'd like
 ...
 yield call(myApiCall)
}

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

Я что-то упускаю из саг? Каков наилучший способ сделать это?

1 Ответ

0 голосов
/ 28 января 2020

Я предлагаю немного изменить вашу программу.

Не стоит отправлять <Modal/> компонент для хранения. Хотя вы можете хранить компонент внутри хранилища, но будет трудно передать правильный props компоненту.

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

// mySaga.js
function* submitForm() {
  yield put({type: SHOW_MODAL, firstModalOpened: true});
  take('FIRST_MODAL_CLOSED');   // Await for modal close action
   ...
  // add as many more modals as I'd like
   ...
  yield call(myApiCall)
}

В React компонент <Modal/> можно использовать следующим образом:

<Modal open={props.firstModalOpened} onClose={() => dispatch({type: 'FIRST_MODAL_CLOSED'})}/>

Если у вас есть несколько модалов, которые будут открыты одновременно, вы можете вызвать пут несколько раз, а затем дождаться завершения всех близких действий, прежде чем перейти к yield call(myApiCall)

yield put({type: SHOW_MODAL, firstModalOpened: true});
yield put({type: SHOW_MODAL, secondModalOpened: true});
yield all([
  take('FIRST_MODAL_CLOSED')
  take('SECOND_MODAL_CLOSED')
]);
...