在 Dan Abramov 看到这个帖子并写出另一个惊人答案之前,我会尝试解释一下:
缺点:
来自 reducer A 的函数可能需要访问 reducer B 中的信息,但由于这种情况无法访问。
实际上这个问题并不会发生,因为你完全可以自己决定如何组合 reducers。如果一个 reducer 只关心 state 树中的一部分,那么 combineReducers
将确保它只收到这部分。但如果它需要更多的状态,则可以以某种方式应用这个特定的 reducer,使其接收整个 state。
最终整个应用程序只会有一个 reducer - 负责处理整个状态和所有操作 - 但你可能希望将应用程序代码分成与主题相关的模块,以便更容易编写较小的主题相关的 reducers,并将它们组合成一个大的 reducer。combineReducers
只是一个助手函数,可以在需要时方便地使用它来实现。
- 更多文件会导致更多混乱和意外错误。
- 不必要的代码拆分......
何时拆分代码取决于你。我喜欢将不相关的功能放在不同的文件中。例如,如果我的 Web 应用程序有一个聊天模块,我可能会创建一个 chat
包,并将所有与聊天相关的代码放入其中 - 视图、一堆操作以及理解这些操作的 reducer。
接下来是优点:
combineReducers
对于可重用的应用程序非常有帮助。例如,我可以编写一个处理评论的模块...... 其中的一部分将是一个 reducer,如下所示:
const initialState = {
commentList: [],
commentingAllowed: true,
}
function commentReducer(state, action) {
if (typeof state === 'undefined') {
return initialState;
}
switch (action.type) {
}
}
但是我的应用程序的实际状态可能更加复杂,例如:
{
currentArticle: {
title: "Some article",
published: "2017-04-05",
author: "someone",
comments: {
commentList: [],
commentingAllowed: true,
}
}
}
评论状态是嵌套在currentArticle
下的,但我的评论应用程序(尤其是commentReducer
)不了解文章的整个概念!因此,我不希望它收到整个状态-它不知道该如何处理。我希望这个reducer只接收与其评论相对应的状态部分。
请注意,我可能同时有许多文章,也可能有其他可评论的东西。通过巧妙地组合reducers,您可以拥有多个评论应用程序的“实例”,每个实例只负责自己的一小部分状态。这需要比单独使用combineReducers
更聪明的粘合代码,但它展示了当reducer只想要特定部分的应用状态时的情况-关注点分离。