redux-saga: функция вызывается дважды - PullRequest
0 голосов
/ 25 марта 2019

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

Я прошел:

Магазин

export default function configureStore(preloadedState) {
  const sagaMiddleware = createSagaMiddleware();
  const middlewares = [..otherMiddleware, sagaMiddleware, ...someMoreMiddlewares];

  const store = createStore({
    // other configuration,
    // middleWares
  })

  sagaMiddleware.run(rootRunner);
  return store;
}

Редуктор :

const initialState = {
  activeSwitch: '1',
  modalVisibility: false,
}

export default function reducer(state = initialState, action) {
  switch (action.type) {
    case 'TOGGLE_MODAL':
      return state.set('modalVisibility', !state.get('modalVisibility'));
    case 'UPDATE_ACTIVE_SWITCH':
      // update active switch
    default:
      return state;
  }
}

Действие :

export const switchOption = payload => ({
  type: 'SWITCH_OPTION',
  payload,
})

export const toggleModal = () => ({
  type: 'TOGGLE_MODAL',
})

export const updateActiveSwitch = payload => ({
  type: 'UPDATE_ACTIVE_SWITCH',
  payload,
})

Компонент :

import switchOption from 'action';

function Component(props) {
  return <div onClick={props.switchOpt(somePayloadParameter)} />;
}

const mapDispatchToProps = state => ({
  switchOpt: (somePayloadParameter) => dispatch(switchOption(somePayloadParameter)),
})

export default connect(null, mapDispatchToProps)(Component);

RootSaga :

export default function* rootRunner() {
  yield all([ fork(watcher) ])
}

Saga :

function* worker(payload) {
  console.log('hey');
  yield put({'TOGGLE_MODAL'})
  // Perform some task and wait for modal ok button click
  yield take('MODAL_OK');
  if (taskSuccess) {
  yield put({ type: 'UPDATE_ACTIVE_SWITCH', someValue});
  yield put({ type: 'TOGGLE_MODAL'}};
}

export default function* watcher() {
  while(true) {
    yield actionObj = yield take('SWITCH_OPTION');
    yield call(worker, actionObj.payload);
  }
}

Модал никогда не виден, поскольку 'TOGGLE_MODAL' отправляется дважды из саги, в результате watcher вызов worker дважды.

Если я поставлю debugger сразу после while(true) { в watcher, при загрузке страницы , эта точка останова будет достигнута дважды.

Даже если я уберу каждую строку из worker, он все еще работает дважды.

Почему мойсаг-код выполняется дважды?


РЕДАКТИРОВАТЬ

Компонент :

import switchOption from 'action';

function Component(props) {
  return <div onClick={props.switchOpt(somePayloadParameter)} />;
}

const mapDispatchToProps = state => ({
  // switchOption is action from action.js
  switchOpt: (somePayloadParameter) => dispatch(switchOption(somePayloadParameter)),
})

export default connect(null, mapDispatchToProps)(Component);

Промежуточное ПО монитора Redux регистрирует консоль в инструментах разработчика после трех действий после выполнения функции saga при первом вызове onClick:

  • 'SWITCH_OPTION'
  • 'TOGGLE_MODAL'-> с modalVisibility, установленным на true
  • ' TOGGLE_MODAL '-> с modalVisibility, установленным на false

Теперь нажмите на divстановится бесполезным, так как MODAL никогда не появляется и нет кнопки OK для нажатия.

1 Ответ

0 голосов
/ 25 марта 2019

Прямо сейчас Component вызывает props.switchOpt каждый раз, когда рендерит.Вместо этого создайте новую функцию, которую можно передать по ссылке, а затем вызывать с помощью onClick:

function Component(props) {
  return <div onClick={() => { props.switchOpt(somePayloadParameter); }} />;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...