【发布时间】:2019-08-15 22:27:47
【问题描述】:
我正在根据在 saga 中间件中执行的一些逻辑的结果通过从 saga 调度操作来切换模式的可见性。
我经历过:
- github上Action is being dispatched twice
-
takeEvery/takeLatest is executed twice even though action dispatched only once
- 帮助不大。
商店
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) ])
}
传奇:
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);
}
}
由于watcher 调用worker 两次,从 saga 分派了两次“TOGGLE_MODAL”,因此模态永远不可见。
如果我在watcher 中的while(true) { 之后放置一个debugger,在页面加载时,该断点会被命中两次。
即使我从worker 中删除每一行,它仍然会运行两次。
为什么我的 saga 代码会运行两次?
编辑
组件:
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 监控中间件在第一次调用onClick 时执行 saga 函数后,通过三个操作登录到开发工具中的控制台:
- 'SWITCH_OPTION'
- 'TOGGLE_MODAL' -->
modalVisibility设置为true - 'TOGGLE_MODAL' -->
modalVisibility设置为false
现在点击div 变得毫无用处,因为 MODAL 从未弹出,也没有 OK 按钮可供点击。
【问题讨论】:
-
也许如果你添加更完整的代码,我们可以看到流程的去向。作为一个松散的尝试示例,我猜在你的 reducer 中,你总是为每种情况都有一个“return”语句,否则 UPDATE_ACTIVE_SWITCH 将被执行两次,第一次是在打开弹出窗口时,第二次是在真正更新开关时。
-
@CarlosRuana,我更新了代码,使其更完整,我似乎无法识别错误,也找不到调试 sagas 的方法。现在我正在阅读github.com/redux-saga/redux-saga/tree/master/examples 中的示例
-
在组件中,您有“switchOption: () => dispatch(toggleVisibility())”,但我没有看到 toggleVisibility 对动作的实现以及与 toggleModal 或减速器的关系。您可以附加该代码中的某些内容吗?
-
@CarlosRuana 请查看问题的编辑部分。我已经更新了原来的问题。
标签: javascript reactjs redux generator redux-saga