【发布时间】:2016-01-30 04:20:09
【问题描述】:
所以我一周前开始学习 React,我不可避免地遇到了状态问题以及组件应该如何与应用程序的其余部分进行通信。我四处搜索,Redux 似乎是这个月的味道。我通读了所有文档,我认为这实际上是一个非常具有革命性的想法。以下是我的想法:
人们普遍认为状态是非常邪恶的,并且是编程中错误的一大来源。与其把它分散在你的应用程序中,Redux 说为什么不把它全部集中在一个你必须发出动作来改变的全局状态树中?听起来不错。所有程序都需要状态,所以让我们把它放在一个不纯的空间里,只从那里修改它,这样错误就很容易追踪。然后我们还可以声明性地将各个状态片段绑定到 React 组件并让它们自动重绘,一切都很漂亮。
但是,我对整个设计有两个问题。一方面,为什么状态树需要是不可变的?假设我不关心时间旅行调试、热重载,并且已经在我的应用程序中实现了撤消/重做。这样做似乎很麻烦:
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;
}
它仍然是一个全局状态树,通过发出的动作进行变异,但非常简单和高效。
【问题讨论】:
-
“一方面,为什么状态树需要是不可变的?” --- 那么您必须提供一种算法来确定数据是否已更改。不可能为任意数据结构(如果它是可变的)实现它。取
immutablejs并使用return state.setIn([action.index, 'completed'], true);来减少样板。 -
PS:
return state.map(i => i.index == action.index ? {...i, completed: true} : i);
标签: javascript reactjs state immutability redux