普通函数与嵌套返回函数差异:Redux Logger写法疑问解析
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:
- First layer (
store => ...): Redux calls this first, passing a limited subset of the store API (includinggetState()and a reference todispatch). This lets your middleware access store state during initialization, or hook into dispatch if needed. - Second layer (
next => ...): Redux then calls this returned function, passing thenextdispatch function in the middleware chain. Thisnextcould be the action handler of the next middleware, or the original store’sdispatchif your middleware is last in the chain. - 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), leavingnextandactionasundefined. - When your code tries to run
result = next(action), you’re attempting to invokeundefinedas 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
nextoractionat 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

