[英]redux-saga: function is called twice
I am toggling visibility of a modal in react based on result of some logic performed in saga middleware by dispatching action from saga.我正在根据在 saga 中间件中通过从 saga 分派动作执行的某些逻辑的结果来切换反应中模态的可见性。
I went through:我经历了:
takeEvery/takeLatest is executed twice even though action dispatched only once即使动作只分派一次,takeEvery/takeLatest 也会执行两次
Store店铺
export default function configureStore(preloadedState) {
const sagaMiddleware = createSagaMiddleware();
const middlewares = [..otherMiddleware, sagaMiddleware, ...someMoreMiddlewares];
const store = createStore({
// other configuration,
// middleWares
})
sagaMiddleware.run(rootRunner);
return store;
}
Reducer :减速机:
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;
}
}
Action :行动:
export const switchOption = payload => ({
type: 'SWITCH_OPTION',
payload,
})
export const toggleModal = () => ({
type: 'TOGGLE_MODAL',
})
export const updateActiveSwitch = payload => ({
type: 'UPDATE_ACTIVE_SWITCH',
payload,
})
Component :组件:
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);
}
}
Modal is never visible as 'TOGGLE_MODAL' is being dispatched twice from saga, as a result of watcher
calling worker
twice.模态永远不可见,因为 'TOGGLE_MODAL' 从 saga 被分派两次,这是
watcher
两次调用worker
的结果。
If I put a debugger
just after while(true) {
in watcher
, on page load , that breakpoint is hit twice.如果我在
while(true) {
in watcher
之后放置一个debugger
,在页面加载时,该断点会被命中两次。
Even if I remove every line from worker
, it is still running twice.即使我从
worker
删除每一行,它仍然运行两次。
Why is my saga code running twice?为什么我的传奇代码运行两次?
EDIT编辑
Component :组件:
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 monitor middleware logs to the console in dev tools following three actions, after executing saga function when it is called onClick
for the first time: Redux 监控中间件在第一次调用
onClick
时执行 saga 函数后,通过三个动作记录到开发工具中的控制台:
modalVisibility
set to true
modalVisibility
设置为true
modalVisibility
set to false
modalVisibility
设置为false
Now the click on div
becomes useless as MODAL never popped up and there is no OK button to click on.现在点击
div
变得无用,因为 MODAL 从未弹出,也没有可以点击的OK按钮。
Right now Component
is calling props.switchOpt
every time it renders.现在
Component
每次渲染时都会调用props.switchOpt
。 Instead, create a new function that can be passed by reference and is then called with onClick
:相反,创建一个可以通过引用传递的新函数,然后使用
onClick
调用:
function Component(props) {
return <div onClick={() => { props.switchOpt(somePayloadParameter); }} />;
}
Use takeLatest helper. 使用takeLatest助手。 It allows the saga generator to only take the latest request
它允许传奇生成器仅接受最新请求
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.