在Redux仓库中的issue 303中,Dan Abramov给出了一个函数示例,该函数可以包装商店的subscribe
方法,以便将之前的状态传递给订阅者。
function observeStore(store, select, onChange) {
let currentState;
function handleChange() {
let nextState = select(store.getState());
if (nextState !== currentState) {
currentState = nextState;
onChange(currentState);
}
}
let unsubscribe = store.subscribe(handleChange);
handleChange();
return unsubscribe;
}
出于某种原因,这对我不起作用。第一次调用我的onChange
处理程序currentState
是undefined
,正如我所期望的那样。但是,在每次后续状态更改时,currentState
的属性值(==
)与nextState
的属性相同。这两个状态对象不是同一个对象,但因为nextState === currentState
的计算结果为false
。
我可能错过了一些非常明显的东西。如何在闭包中捕获先前的状态?
答案 0 :(得分:2)
问题是我的reducer实际上并没有创建一个新的状态实例,即我正在改变状态,而不是返回一个新的副本。我的reducer代码类似于:
const newState = Object.assign({}, state);
newState.my.prop = …;
return newState;
但是,Object.assign
和ES2015解构分配只执行浅副本,这意味着它们只影响一个级别的深度。在我的应用程序中,我正在更新的状态是三个级别。我在减速器中使用了一个快速,肮脏,丑陋的黑客来测试我的理论:
const newState = JSON.parse(JSON.stringify(state)); // <-- Yuck!
newState.my.prop = …;
return newState;
不要在家尝试。不过,这是我的第一个线索。一个正确的实现将使用类似Facebook的Immutable库来确保每个突变产生一个新的克隆。