【问题标题】:redux sagas are blocking the browserredux sagas 阻塞了浏览器
【发布时间】:2018-03-08 16:21:00
【问题描述】:

我对 sagas 完全陌生。

最近我正在为我未来的项目试验一个基础设施,包括react-router v4 和 sagas。

按照 sagas 的初学者教程和对此事的一些调查,我创建了一个近似值,这个想法是让每个连接到 redux 的组件成为它自己的“微宇宙”,并拥有它自己的 reducer,当然它自己的 sagas 文件。

好了,看代码吧,下面是组件文件夹和src文件夹的基本结构:

src/
  +components/
    +foo-component/
      -actions.js
      -constants.js
      -defaultState.js
      -index.js
      -reducer.js
      -sagas.js
-App.js
-index.js
-rootReducer.js
-rootSagas.js
-store.js

现在,这是我的sagas.js 文件foo-component,我创建了worker saga 和watcher saga,然后我将它们导出为一个数组以在rootSagas.js 中使用:

import { put, takeEvery } from 'redux-saga/effects'
import { COUNT } from './actions'

// Worker count
function* count() {
  yield put({ type: COUNT })
}

// Watcher helloSaga
function* watchCount() {
  yield takeEvery(COUNT, count)
}

const CounterSagas = [
  count(),
  watchCount()
]

export default CounterSagas

rootSagas.js 文件中,我得到了这个 sagas 并导出了一个入口点,该入口点同时产生了所有 sagas:

import { all } from 'redux-saga/effects'

// sagas
import CounterSagas from './components/counter/sagas'

// run all
export default function* rootSagas() {
  yield all([
    // decompose
    ...CounterSagas,
  ])
}

最后,在 store config 中启动 sagas:

import { compose, applyMiddleware, createStore } from 'redux'
import createSagaMiddleware from 'redux-saga'
import rootReducer from './rootReducer'
import rootSagas from './rootSagas'

let store
const sagaMiddleware = createSagaMiddleware()

if (process.env.NODE_ENV === 'production') {
  store = createStore(
    rootReducer,
    applyMiddleware(sagaMiddleware)
  )
} else {
  store = createStore(
    rootReducer,
    compose(
      applyMiddleware(sagaMiddleware),
      window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
    )
  )
}

sagaMiddleware.run(rootSagas)

export default store
export const action = (type, payload) => store.dispatch({type, payload})

好的,我有两个问题:

  1. counter saga 会自动触发一次(不是当事件被按钮触发时)。

  2. 当我触发动作 COUNT 时,浏览器进入无限循环并被阻塞:

错误:在你的一个组件中抛出了一个错误,但 React 不知道它是什么。这可能是由于浏览器的脆弱性。 React 尽最大努力保留 DevTools 的“异常暂停”行为,这需要一些仅 DEV 模式的技巧。这些可能在您的浏览器中不起作用。尝试在生产模式下触发错误,或切换到现代浏览器。如果您怀疑这实际上是 React 的问题,请提出问题。

我知道,这是我说出来的经验不足,所以有人可以给我一些指导吗?

谢谢

【问题讨论】:

    标签: javascript reactjs redux-saga


    【解决方案1】:

    解决了!问题出在middleware.run(sagas) 中,删除它一切正常。

    【讨论】:

      【解决方案2】:

      通过删除 middleware.run(sagas) saga 实际上会被禁用。事实上,问题在于,当您调度动作时,它将转到 saga 中间件,在中间件中我们使用 put 方法(在 watch 之后)而不是调度,这将导致无限调度相同的动作。问题将通过重命名 takeEvery 方法第一个参数中的动作类型或 saga 动作类型来解决,它们不应该相同!像这样:

       // Watcher helloSaga
      function* watchCount() {
        yield takeEvery(A_COUNT, count)
      }
      

      【讨论】: