You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

普通函数与嵌套返回函数差异:Redux Logger写法疑问解析

Why Do These Two Redux Logger Implementations Behave Differently?

Great question—this cuts straight to how Redux middleware is designed to work under the hood. Let’s break down the key differences and why only the multi-layered function version actually works as intended.

Redux Middleware Requires a Curried Function Structure

Redux’s middleware system is built around function currying—a pattern where functions are called sequentially, one argument at a time. Every valid Redux middleware must follow this mandatory structure:

const middleware = store => next => action => {
  // Middleware logic goes here
}

Here’s what each layer does when Redux processes your middleware:

  1. First layer (store => ...): Redux calls this first, passing a limited subset of the store API (including getState() and a reference to dispatch). This lets your middleware access store state during initialization, or hook into dispatch if needed.
  2. Second layer (next => ...): Redux then calls this returned function, passing the next dispatch function in the middleware chain. This next could be the action handler of the next middleware, or the original store’s dispatch if your middleware is last in the chain.
  3. Third layer (action => ...): This is the function that runs every time an action is dispatched. It’s where you add your logging logic, modify the action, or control whether it proceeds to the next step in the chain.

Why the Single-Function Version Fails

Your second implementation:

const logger = (store, next, action) => {
  // Logging logic here
}

Violates Redux’s middleware contract entirely. Here’s what happens when you try to use it:

  • Redux will first call logger(storeAPI) (only passing the store argument), leaving next and action as undefined.
  • When your code tries to run result = next(action), you’re attempting to invoke undefined as a function—this will throw a runtime error immediately.
  • The function never gets the chance to handle any actions, because it’s not structured to receive next or action at the right points in Redux’s middleware pipeline.

Simplified Look at How Redux Processes Middleware

To make this concrete, here’s a stripped-down version of what applyMiddleware does:

function applyMiddleware(...middlewares) {
  return createStore => (...args) => {
    const store = createStore(...args);
    const middlewareAPI = { getState: store.getState, dispatch: store.dispatch };
    
    // Step 1: Initialize each middleware with the store API
    const chain = middlewares.map(middleware => middleware(middlewareAPI));
    // Step 2: Chain middleware together into a single dispatch function
    const enhancedDispatch = chain.reduce((prev, curr) => curr(prev), store.dispatch);
    
    return { ...store, dispatch: enhancedDispatch };
  };
}

You can see that each middleware is only passed one argument initially. The multi-layered function returns a new function to accept next, then another to accept action—this is exactly what Redux needs to build the middleware chain correctly.

Key Takeaway

The multi-layered function structure isn’t just a style choice—it’s how Redux’s middleware system is designed to operate. It lets middleware:

  • Access store state during setup
  • Chain seamlessly with other middleware
  • Run logic every time an action is dispatched

The single-function version breaks this pattern entirely, so it can’t integrate with Redux’s pipeline at all.

内容的提问来源于stack exchange,提问作者Aran Freel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:42:58