在 Redux 中使 Reducer 不可变

Eve*_*erg 0 javascript reactjs immutable.js redux

我刚刚开始使用 ImmutableJS,我想使 reducer 变得不可变。我读过我需要将我的减速器转换回来才能使其正常工作。任何人都可以想出如何使这项工作的答案?本身我收到错误消息:“INCREASE_NUMBER.toObject() 不是函数”这是代码(如下):

import { INCREMENT } from '../actionTypes/default'
import { Map, toObject } from 'immutable'

const INCREASE_NUMBER = (state = Map({number: 0}), action) => {
  switch(action.type) {
    case INCREMENT:
    return state.merge({number: state.number + 1})
    default:
    return state
  }
};
INCREASE_NUMBER.toObject()

module.exports = INCREASE_NUMBER
Run Code Online (Sandbox Code Playgroud)

Tha*_*you 5

根据您的问题,您似乎不太了解不变性,因此我首先质疑您需要使用 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
Run Code Online (Sandbox Code Playgroud)

这里没有突变。按照这段代码的编写方式,变异从根本上是不可能的。我们正在从中读取一个值,state但这里没有可以写入现有state对象的代码。state不是一个不可变的对象,但你也不是一个愚蠢的开发者。如果你写了一些代码来改变state对象,那是你自己的错。如果你在电源插座里到处乱摸,只能怪你自己。

我可以很容易地写

// non-mutating state transformation
case INCREMENT:
  return Object.assign({}, state, {number: state.number + 1})
Run Code Online (Sandbox Code Playgroud)

...你应该知道这与

// mutating state transformation
case INCREMENT:
  return Object.assign(state, {number: state.number + 1})
Run Code Online (Sandbox Code Playgroud)

同样,你应该知道两者之间的区别

// non-mutating array transformation
[1,2,3].concat([4])
Run Code Online (Sandbox Code Playgroud)

... 和这个

// mutating array transformation
[1,2,3].push(4)
Run Code Online (Sandbox Code Playgroud)

这个怎么样

// mutating sort
[4,2,1,3].sort()
Run Code Online (Sandbox Code Playgroud)

... 和这个

// non-mutating sort
[4,2,1,3].slice(0).sort()
Run Code Online (Sandbox Code Playgroud)

当然,如果您有一个大型应用程序,有人可能会争辩说,在您的数据周围添加一个小的不变性安全预防措施是有意义的。这可能会防止无知的开发人员在不应该发生的情况下意外变异state。对我来说,这不是一个有效的解决方案。如果这是一个 redux 应用,你的开发人员应该对 redux 哲学有深入的了解,这意味着 reducer 是纯函数,state永远不会被变异......知识和智慧是无可替代的。

深入了解 JavaScript。了解您正在使用的工具。确定各种方法的优缺点。了解各种技术的“成本”。知道何时何地可以做出妥协。如果您最终仍决定使用 ImmutableJS,您就会知道为什么选择它,并且会知道随之而来的收益/损失。