Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Redux-在中间件内部调用storeAPI.disapatch(操作)会导致';太多的递归';_Javascript_Reactjs_Redux_React Redux - Fatal编程技术网

Javascript Redux-在中间件内部调用storeAPI.disapatch(操作)会导致';太多的递归';

Javascript Redux-在中间件内部调用storeAPI.disapatch(操作)会导致';太多的递归';,javascript,reactjs,redux,react-redux,Javascript,Reactjs,Redux,React Redux,我正在学习Redux基础教程。在上一节中,我们了解到中间件是作为一系列三个嵌套函数编写的,如下所示: // Outer function: function exampleMiddleware(storeAPI) { return function wrapDispatch(next) { return function handleAction(action) { // Do anything here: pass the action onwards with nex

我正在学习Redux基础教程。在上一节中,我们了解到中间件是作为一系列三个嵌套函数编写的,如下所示:

// Outer function:
function exampleMiddleware(storeAPI) {
  return function wrapDispatch(next) {
    return function handleAction(action) {
      // Do anything here: pass the action onwards with next(action),
      // or restart the pipeline with storeAPI.dispatch(action)
      // Can also use storeAPI.getState() here

      return next(action)
    }
  }
}
示例中间件
解释如下:

示例中间件:外部功能实际上是“中间件” 它本身它将被applyMiddleware调用,接收storeAPI 对象,该对象包含存储的{dispatch,getState}函数。这些 实际上是的一部分的dispatch和getState函数是相同的 商店如果调用此分派函数,它将发送操作 到中间件管道的开始。这只调用一次

我不明白最后一句话的意思(
如果调用此分派函数,它会将操作发送到中间件管道的开始处,因此我尝试调用
store.dispatch(操作)
在示例应用程序的
src/exampleAddons/middleware.js中提供的一个中间件中,查看发生了什么,并得到了“太多递归”

因此,
storeAPI.dispatch()
是所有中间件组合的组合调度函数,而不是原始商店的
调度
,这将解释递归那么
storeAPI.dispatch()有什么用呢?我用错了吗?

applyMiddleware
中:


无限循环似乎是上述注释中步骤5重新赋值的结果。但我不确定我的推理是否正确,或者我是否正确使用了
storeAPI.dispatch
。我希望社区能在这里提供任何指导,因为我找不到任何调用
storeAPI.dispatch()

的中间件示例。是的,在中间件中调用
storeAPI.dispatch()
将操作发送到中间件管道的最开始。这意味着,如果我们有中间件
a->b->c->store
,并且
b
调用
storeAPI.dispatch({type:'some/action})
,中间件
b
将几乎立即看到完全相同的操作对象

因此,中间件永远不应该无条件地调用
storeAPI.dispatch()
,因为这将导致无限循环
这与在React组件
useffect
hook中无条件调用
setState()
基本相同。效果在渲染后运行,并且
setState()
将另一个渲染排队,因此如果每次都设置状态,则始终强制重新渲染,这是一个无限循环。这里也一样


因此,任何在中间件中使用
storeAPI.dispatch()
的行为都应该被包装在一个条件检查中,这样它只会在一段时间内发生,而不是在所有时间内发生。

为使用提供了一些启示
storeAPI.dispatch
对于在中间件中有条件地分派操作似乎很有用,例如,
if(条件){storeAPI.dispatch(someOtherAction)}else{next(action)}
-如果条件为true,则someOtherAction将通过中间件管道传递,否则,当前操作将传递给下一个中间件。您可以看到此模式正在使用中。在文档中提供一个这样的示例会有所帮助。我知道
storeAPI.dispatch
会“重启”中间件链,但在我看到之前评论中的链接之前,我不确定为什么这是一个有用的功能。将再次分派操作,这样redux将再次运行调用
storeAPI.dispatch(action)
的中间件,这样redux将再次运行调用
storeAPI.dispatch(action)
的中间件,这是无限循环。这就像编写一个永不停止循环的递归函数:
const-thunk-middleware=(arg)=>recur(arg)
如果你看一个thunk实现,你会发现如果操作是一个函数,它不会调用next:
const-thunk-middleware=({getState,dispatch})=>next=>action=>typeof-action=='function'?action(dispatch,getState):下一步(action)
谢谢@markerikson,我没有想到它应该有条件地使用。这正是它的用途。
function applyMiddleware(...middlewares) {
  return createStore => (...args) => {
    // ...1) createStore is called and the resulting store is saved as `store`
    const store = createStore(...args)
    
    // ...2) a `dispatch` variable is defined and assigned some function
    let dispatch = () => {
      throw new Error(
        'Dispatching while constructing your middleware is not allowed. ' +
          'Other middleware would not be applied to this dispatch.'
      )
    }
    
    // ...3) a middlewareAPI object is defined containing the store's getState method and the `dispatch` function from 2).
    const middlewareAPI = {
      getState: store.getState,
      dispatch: (...args) => dispatch(...args)
    }
    
    // ...4) the middlewares passed to applyMiddleware are called with the `middlewareAPI` object from 3) and the resulting functions are saved in array `chain`.
    const chain = middlewares.map(middleware => middleware(middlewareAPI))
    
    // ...5) the middlewares are composed and the resulting "composed" middleware function is called with `store.dispatch`. 
    // This returns a composed dispatch function that chains together the `handleAction` functions of all the middlewares passed to applyMiddleware. 
    // This composed dispatch gets assigned to the `dispatch` variable from 2). 
    // Since the `storeAPI.dispatch` is referencing this variable, calling `storeAPI.dispatch` now calls the composed middleware function, which causes the infinite loop. 
    dispatch = compose(...chain)(store.dispatch)

    return {
      ...store,
      dispatch
    }
  }
}