根据您的问题,您似乎不太了解不可变性,因此我首先质疑您需要使用 ImmutableJS 的合法性。您不必使用 ImmutableJS 来编写非变异状态转换。
我不需要插座盖来防止自己将金属物体插入电源插座。我宁愿不触电,所以我不会随便往插座里戳东西。没有比这更复杂的了。
您最好深入了解您正在使用的工具。您应该知道 JavaScript 运算符/函数/方法何时改变数据,何时不改变。如果你认为 ImmutableJS 可以保护你免受自己的无知,那你就大错特错了。您有时会遇到问题并且不知道如何诊断它们,因为您没有花时间了解自己在做什么。
你的 reducer 可以用严肃的 vanilla JavaScript 编写
import { INCREMENT } from '../actionTypes/default'
const initialState = {number: 0}
const increaseNumberReducer = (state, action) => {
switch (action.type) {
case INCREMENT:
return {number: state.number + 1}
default:
return state
}
}
export default increaseNumberReducer
这里没有突变。以这种代码的编写方式,突变基本上是不可能的。我们正在读取来自state 的值,但这里没有代码可以写入 到现有的state 对象。 state 不是一个不可变 对象,但你也不是一个愚蠢的开发者。如果您编写了一些代码来改变state 对象,那是您自己的错。如果你在电源插座上乱摸,那只能怪你自己。
我也可以这么轻松地写
// non-mutating state transformation
case INCREMENT:
return Object.assign({}, state, {number: state.number + 1})
...你应该知道它与
有什么不同
// mutating state transformation
case INCREMENT:
return Object.assign(state, {number: state.number + 1})
同样,你应该知道两者的区别
// non-mutating array transformation
[1,2,3].concat([4])
...还有这个
// mutating array transformation
[1,2,3].push(4)
这个怎么样
// mutating sort
[4,2,1,3].sort()
...还有这个
// non-mutating sort
[4,2,1,3].slice(0).sort()
当然,如果您有一个大型应用程序,有人可能会认为在您的数据周围添加一个小的不变性安全预防措施是有意义的。这可能会防止无知的开发人员在不应该的情况下意外改变state。对我来说,这不是一个有效的解决方案。如果这是一个 redux 应用程序,您的开发人员应该对 redux 哲学有深入的了解,这意味着 reducer 是纯函数,state 永远不会被变异......知识和智慧是无可替代的。
深入了解 JavaScript。了解您正在使用的工具。确定各种方法的优缺点。了解各种技术的“成本”。知道何时何地可以做出妥协。如果你最终还是决定使用 ImmutableJS,你就会知道为什么你选择了它,你也会知道它带来的收益/损失。