redux-saga:函数被调用两次

Har*_*rma 5 javascript generator reactjs redux redux-saga

我通过从 saga 分派操作,根据 saga 中间件中执行的某些逻辑的结果来切换 React 中模态的可见性。

我经历了:

店铺

export default function configureStore(preloadedState) {
  const sagaMiddleware = createSagaMiddleware();
  const middlewares = [..otherMiddleware, sagaMiddleware, ...someMoreMiddlewares];

  const store = createStore({
    // other configuration,
    // middleWares
  })

  sagaMiddleware.run(rootRunner);
  return store;
}
Run Code Online (Sandbox Code Playgroud)

减速机:

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;
  }
}
Run Code Online (Sandbox Code Playgroud)

行动:

export const switchOption = payload => ({
  type: 'SWITCH_OPTION',
  payload,
})

export const toggleModal = () => ({
  type: 'TOGGLE_MODAL',
})

export const updateActiveSwitch = payload => ({
  type: 'UPDATE_ACTIVE_SWITCH',
  payload,
})
Run Code Online (Sandbox Code Playgroud)

成分:

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);
Run Code Online (Sandbox Code Playgroud)

根传奇:

export default function* rootRunner() {
  yield all([ fork(watcher) ])
}
Run Code Online (Sandbox Code Playgroud)

佐贺:

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);
  }
}
Run Code Online (Sandbox Code Playgroud)

Modal 永远不可见,因为由于调用两次,“TOGGLE_MODAL”从 saga 中分派了watcher两次worker。

如果我在页面加载时在in之后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);
Run Code Online (Sandbox Code Playgroud)

onClick在第一次调用 saga 函数后, Redux 监控中间件会通过以下三个操作将日志记录到开发工具中的控制台:

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

现在,单击div变得毫无用处,因为 MODAL 从未弹出,也没有可供单击的“确定”按钮。

Ros*_*len 0

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

function Component(props) {
  return <div onClick={() => { props.switchOpt(somePayloadParameter); }} />;
}
Run Code Online (Sandbox Code Playgroud)