immer中的"Data not originating from the state will never be drafted"是什么意思

What is meant by "Data not originating from the state will never be drafted" in immer

我对 immer 文档的 this 部分感到困惑。我创建了一个更简单的示例来测试相同的原理,即向草稿数据结构添加一些新对象然后修改它。根据文档还应该修改原始数据结构:

import { produce } from "immer";

function print(obj) {
  console.log(JSON.stringify(obj));
}

var todos = [
  { id: 0, done: false },
  { id: 1, done: false }
];

function onReceiveTodo(todo) {
  return produce(todos, draft => {
    draft[1] = todo;
    draft[1].done = true;
  });
}

let nextTodos = onReceiveTodo({ id: 3, done: false });
print(todos);
print(nextTodos);

// [{"id":0,"done":false},{"id":1,"done":false}] // todos
// [{"id":0,"done":false},{"id":3,"done":true}] // nextTodos

但这似乎有效。

有人可以更详细地解释一下这个陷阱吗?

注意:我也尝试使用与文档中完全相同的示例,但对数据结构 todos 应该是什么样子感到困惑。由于 draft 绑定到 todos 的原始版本,因此这一行:draft.todos[todo.id] = todo 表明我们有类似 todos = {todos: {0: {done: false}, 1: {done: false},...} 的东西,但是 todo.id 表明 todo 对象包含 id.

它是关于“如果你在 produce 中传递并改变一个对象,它实际上已经改变了”。

Could someone please explain this pitfall in a bit more detail?

基本上当你这样做时:

let nextTodos = onReceiveTodo({ id: 3, done: false });

可以更改原始对象。考虑一下:

const todo = { id: 3, done: false };
let nextTodos = onReceiveTodo(todo);
todo.done; // true, this object was mutated outside of Immer