redux-saga:函数被调用两次

时间:2019-03-25 16:03:22

标签: javascript reactjs redux generator redux-saga

我基于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);

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后)时,需要执行以下三个操作,将日志记录到开发工具中的控制台中:

  • “ SWITCH_OPTION”
  • 'TOGGLE_MODAL'->,其中modalVisibility设置为true
  • 'TOGGLE_MODAL'->,其中modalVisibility设置为false

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

1 个答案:

答案 0 :(得分:0)

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

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