减速器和中间件有什么区别?

What is the difference between a reducer and middleware?

我在理解减速器和中间件之间的应用差异时遇到了一些困难。许多网站描述了中间件,甚至给出了精确的定义:

It provides a third-party extension point between dispatching an action, and the moment it reaches the reducer.

或:

Middleware is created by composing functionality that wraps separate cross-cutting concerns which are not part of your main execution task.

但据我所知,的区别,而不是什么。据我所知,不同之处在于,一个采取行动并传递该行动,另一个采取行动和状态并 "passes the state on"。但是您仍然可以访问中间件中的商店。所以 store 和 action 都经过中间件,然后是 reducer。所以减速器可以执行日志记录。

虽然日志记录似乎是中间件的明显应用,但还有更多模棱两可的示例。例如,将一些简单的身份验证写入模块,您可以使用中间件函数来执行用户发送的操作并确定他们的身份验证级别:

import { getAuthLevel } from './auth';

export default store => next => action => {
  return next({...action, auth: getAuthLevel(action.clientId)});
}

您可能有一群这样的用户:

{
users: [{
  clientId: 'bobsUnqiueClientId',
  user: 'Bob',
  password: 'ilikecats',
  authlevel: 'OVERLORD'
}, {
  clientId: 'anotherUniqueClientId',
  user: 'Alice',
  password: 'boblikescats',
  authlevel: 'MINION'
}]}

那么您可能会有对应于不同身份验证级别的操作。您可以使用中间件对其进行映射,但您需要了解有关正在执行的操作的更多具体细节,并且看起来需要更多 "execution-related" 代码。但是它不需要知道任何关于状态的信息。它只需要决定将哪些操作转发给减速器。

所以呢?这样的代码会放在 reducer 中还是中间件中?谁能提供其他具体的例子来阐明两者之间的区别?

A reducer 是一个函数,它将状态的一部分和当前调度的操作作为参数,returns 更新状态。多个 reducer 函数可以组合在一起形成您传递给 createStore()root reducer 函数。 Reducers 应该 是 "pure functions",没有 "side effects"。这意味着没有 AJAX 调用,没有调度操作,并且(理论上)没有日志记录 - 只是 (state, action) => newState。 (现在,您 可以 在 reducer 中进行登录,并且该代码可以正常工作,但原则上这仍然不是 reducer supposed 做。)

一个中间件是一段代码,包裹着商店的dispatch功能。多个中间件可以通过 applyMiddleware() 增强器变成一个管道。当一个动作被调度时,它会依次传递给管道中的每个中间件。每个中间件都可以对操作做任何它想做的事情:记录它、延迟它、修改它、分派其他东西,或者只是将它向下传递到管道中。最终,最后一个中间件将操作传递给实际的 store.dispatch() 函数,该函数调用根减速器并启动状态更新逻辑。

所以是的,一般来说,中间件提供了一个地方来执行与操作相关的集中逻辑,例如授权检查或日志记录。

您可能想阅读 Structuring Reducers section in the Redux docs for more examples of how reducers work and can be organized, and my React/Redux links list has sections of articles discussing Redux middleware and reducer usage