Я переключаю видимость модальности в реакции на основе результата некоторой логики, выполняемой в промежуточном программном обеспечении саги путем отправки действия из саги.
Я прошел:
Магазин
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 для нажатия.