繁体   English   中英

redux-saga:函数被调用两次

[英]redux-saga: function is called twice

我正在根据在 saga 中间件中通过从 saga 分派动作执行的某些逻辑的结果来切换反应中模态的可见性。

我经历了:

店铺

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);

根传奇

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);
  }
}

模态永远不可见,因为 'TOGGLE_MODAL' 从 saga 被分派两次,这是watcher两次调用worker的结果。

如果我在while(true) { in watcher之后放置一个debugger在页面加载时,该断点会被命中两次。

即使我从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 监控中间件在第一次调用onClick时执行 saga 函数后,通过三个动作记录到开发工具中的控制台:

  • 'SWITCH_OPTION'
  • 'TOGGLE_MODAL' --> modalVisibility设置为true
  • 'TOGGLE_MODAL' --> modalVisibility设置为false

现在点击div变得无用,因为 MODAL 从未弹出,也没有可以点击的OK按钮。

现在Component每次渲染时都会调用props.switchOpt 相反,创建一个可以通过引用传递的新函数,然后使用onClick调用:

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

使用takeLatest助手。 它允许传奇生成器仅接受最新请求

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM