Redux 不只是美化了全局状态吗?
Isn't Redux just glorified global state?
所以我一周前开始学习 React,我不可避免地遇到了状态问题以及组件应该如何与应用程序的其余部分进行通信。我四处搜索了一下,Redux 似乎是这个月的热门话题。我通读了所有文档,我认为这实际上是一个非常革命性的想法。以下是我对此的看法:
状态通常被认为是非常邪恶的,并且是编程中大量错误的来源。与其将它分散在你的应用程序中,Redux 说为什么不把它全部集中在一个你必须发出动作来改变的全局状态树中?听起来不错。所有的程序都需要状态,所以让我们把它放在一个不纯的 space 中,并且只从那里修改它,这样 bug 就很容易被追踪到。然后我们还可以声明性地将各个状态块绑定到 React 组件并让它们自动重绘,一切都很漂亮。
但是,我对整个设计有两个问题。首先,为什么状态树需要是不可变的?假设我不关心时间旅行调试、热重载,并且已经在我的应用程序中实现了 undo/redo。这样做似乎很麻烦:
case COMPLETE_TODO:
return [
...state.slice(0, action.index),
Object.assign({}, state[action.index], {
completed: true
}),
...state.slice(action.index + 1)
];
而不是这个:
case COMPLETE_TODO:
state[action.index].completed = true;
更何况我正在制作一个在线白板只是为了学习,每个状态的变化可能就像在命令列表中添加一个笔触一样简单。一段时间后(数百个笔触)复制整个阵列可能会开始变得极其昂贵和耗时。
我同意独立于 UI 的全局状态树,通过操作改变它,但它真的需要不可变吗?像这样一个简单的实现有什么问题(非常粗略的草稿。1分钟写成)?
var store = { items: [] };
export function getState() {
return store;
}
export function addTodo(text) {
store.items.push({ "text": text, "completed", false});
}
export function completeTodo(index) {
store.items[index].completed = true;
}
它仍然是一个全局状态树,通过发出的动作进行变异,但非常简单和高效。
Isn't Redux just glorified global state?
当然是。但同样适用于您曾经使用过的每个数据库。最好将 Redux 视为内存中的数据库——您的组件可以响应式地依赖它。
不变性可以非常有效地检查是否有任何子树被更改,因为它简化了身份检查。
是的,您的实现很高效,但是每次以某种方式操纵树时都必须重新渲染整个虚拟 dom。
如果您使用的是 React,它最终会与实际 dom 进行比较并执行最少的批处理优化操作,但完整的自上而下重新渲染仍然效率低下。
对于不可变树,无状态组件只需检查它所依赖的子树是否与先前的值相比具有不同的身份,如果是,则可以完全避免渲染。
是的!
由于没有管理谁可以将特定 property/variable/entry 写入商店,实际上您可以从任何地方 dispatch
任何 action
,因此代码往往更难维护,甚至更难维护当您的代码库增长时 and/or 由多个人管理。
当我开始使用 Redux 时,我遇到了同样的问题,所以我创建了一个库来解决这些问题:
它被称为 Yassi:
Yassi 通过使用注释(使用 @yassit('someName')
)
零样板声明商店条目来解决您提到的问题
更新该条目的值不需要 actions/reducers 或其他此类繁琐的代码片段,而只需更新变量
所以我一周前开始学习 React,我不可避免地遇到了状态问题以及组件应该如何与应用程序的其余部分进行通信。我四处搜索了一下,Redux 似乎是这个月的热门话题。我通读了所有文档,我认为这实际上是一个非常革命性的想法。以下是我对此的看法:
状态通常被认为是非常邪恶的,并且是编程中大量错误的来源。与其将它分散在你的应用程序中,Redux 说为什么不把它全部集中在一个你必须发出动作来改变的全局状态树中?听起来不错。所有的程序都需要状态,所以让我们把它放在一个不纯的 space 中,并且只从那里修改它,这样 bug 就很容易被追踪到。然后我们还可以声明性地将各个状态块绑定到 React 组件并让它们自动重绘,一切都很漂亮。
但是,我对整个设计有两个问题。首先,为什么状态树需要是不可变的?假设我不关心时间旅行调试、热重载,并且已经在我的应用程序中实现了 undo/redo。这样做似乎很麻烦:
case COMPLETE_TODO:
return [
...state.slice(0, action.index),
Object.assign({}, state[action.index], {
completed: true
}),
...state.slice(action.index + 1)
];
而不是这个:
case COMPLETE_TODO:
state[action.index].completed = true;
更何况我正在制作一个在线白板只是为了学习,每个状态的变化可能就像在命令列表中添加一个笔触一样简单。一段时间后(数百个笔触)复制整个阵列可能会开始变得极其昂贵和耗时。
我同意独立于 UI 的全局状态树,通过操作改变它,但它真的需要不可变吗?像这样一个简单的实现有什么问题(非常粗略的草稿。1分钟写成)?
var store = { items: [] };
export function getState() {
return store;
}
export function addTodo(text) {
store.items.push({ "text": text, "completed", false});
}
export function completeTodo(index) {
store.items[index].completed = true;
}
它仍然是一个全局状态树,通过发出的动作进行变异,但非常简单和高效。
Isn't Redux just glorified global state?
当然是。但同样适用于您曾经使用过的每个数据库。最好将 Redux 视为内存中的数据库——您的组件可以响应式地依赖它。
不变性可以非常有效地检查是否有任何子树被更改,因为它简化了身份检查。
是的,您的实现很高效,但是每次以某种方式操纵树时都必须重新渲染整个虚拟 dom。
如果您使用的是 React,它最终会与实际 dom 进行比较并执行最少的批处理优化操作,但完整的自上而下重新渲染仍然效率低下。
对于不可变树,无状态组件只需检查它所依赖的子树是否与先前的值相比具有不同的身份,如果是,则可以完全避免渲染。
是的!
由于没有管理谁可以将特定 property/variable/entry 写入商店,实际上您可以从任何地方 dispatch
任何 action
,因此代码往往更难维护,甚至更难维护当您的代码库增长时 and/or 由多个人管理。
当我开始使用 Redux 时,我遇到了同样的问题,所以我创建了一个库来解决这些问题:
它被称为 Yassi:
Yassi 通过使用注释(使用 @yassit('someName')
)
零样板声明商店条目来解决您提到的问题
更新该条目的值不需要 actions/reducers 或其他此类繁琐的代码片段,而只需更新变量