我基于saga中间件中执行的某些逻辑的结果,通过从saga调度动作来切换反应模式的可见性。
我经历了:
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
的结果,模版从未出现过,因为'TOGGLE_MODAL'从传奇中被分派了两次。
如果我在页面加载上的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
后)时,需要执行以下三个操作,将日志记录到开发工具中的控制台中:
modalVisibility
设置为true
modalVisibility
设置为false
现在,div
的点击变得无用,因为MODAL从未弹出,并且没有 OK 按钮可以点击。
答案 0 :(得分:0)
现在Component
每次渲染时都在调用props.switchOpt
。而是创建一个可以通过引用传递的新函数,然后使用onClick
进行调用:
function Component(props) {
return <div onClick={() => { props.switchOpt(somePayloadParameter); }} />;
}