Javascript 在redux中使用不可变数据结构时,为什么选择器总是返回不可变。?

Javascript 在redux中使用不可变数据结构时,为什么选择器总是返回不可变。?,javascript,redux,react-redux,immutable.js,reselect,Javascript,Redux,React Redux,Immutable.js,Reselect,根据此处的redux常见问题解答: 选择器应返回Immutable.JS对象。总是 为什么会这样?作为免责声明,情况并非总是如此,但文档试图为大多数情况指明正确的方向 由于重新选择会记忆选择器的返回结果,因此返回可变对象会使您容易受到棘手错误的影响。想象一下以下场景: // Immutable State { todos: [{ text: "hey"}, { todo: "text"}] } // Selectors const getTodos = createSelector(st

根据此处的redux常见问题解答:

选择器应返回Immutable.JS对象。总是


为什么会这样?

作为免责声明,情况并非总是如此,但文档试图为大多数情况指明正确的方向

由于重新选择会记忆选择器的返回结果,因此返回可变对象会使您容易受到棘手错误的影响。想象一下以下场景:

// Immutable State
{
  todos: [{ text: "hey"}, { todo: "text"}]
}

// Selectors

const getTodos = createSelector(state => state.todos, immutableTodos => immutableTodos.toJS())
getToOS选择器返回一个普通JS对象,默认情况下该对象是可变的。现在想象一下,多个智能组件正在使用gettoos选择器

class EditTodos extends PureComponent {
  constructor(props) {
    this.state = { todos: props.todos }
  }

  addUnsavedTodo(newTodo) {
    // Accidentally mutate the return result of getTodos
    const newTodos = this.state.todos.push(newTodo)
    this.setState({ todos: newTodos })
  }

  render() { // Some components for adding unsaved todos }
}

const mapStateToProps = (state) => ({ todos: getTodos(state))
第二个组件也使用getTodos,在调用addUnsavedTodo时会看到新的未保存的todo,这很可能是无意的。假设redux状态不变,所有对gettoos的调用都将得到相同的引用,任何突变都将影响所有使用者

上面的示例是人为设计的,但希望它能说明返回普通JS对象可能有风险的原因之一


此外,作为文档,您应该限制toJS的使用,因为它会影响性能。将不可变对象转换为选择器中的普通JS对象没有任何好处

如果我不将toJS放在选择器中,我应该把它放在哪里?创建一个额外的容器组件来调用toJS似乎太多余了,或者你不这么认为。最简单的方法是在组件内部使用ImmutableJS,这样你就不必调用toJS了。如果我能更详细地了解你想要实现的目标,那会有帮助的。你有到github gist或回购的链接吗?你的帖子和评论为我澄清了这一点。谢谢!