数组方法
Immer 支持所有标准的数组方法,并且可以像操作普通数组一样操作 draft 数组。下面是一些常见的数组操作示例:
添加元素
javascript
import produce from "immer"
const todos = [
{ id: 1, text: "学习 Immer", done: false },
{ id: 2, text: "构建应用", done: false }
]
const newTodos = produce(todos, draft => {
// 添加到数组末尾
draft.push({ id: 3, text: "编写文档", done: false })
// 添加到数组开头
draft.unshift({ id: 0, text: "初始化项目", done: true })
// 在指定位置插入
draft.splice(2, 0, { id: 1.5, text: "深入学习", done: false })
})删除元素
javascript
const todos = [
{ id: 1, text: "学习 Immer", done: false },
{ id: 2, text: "构建应用", done: false },
{ id: 3, text: "编写文档", done: false }
]
const newTodos = produce(todos, draft => {
// 删除最后一个元素
draft.pop()
// 删除第一个元素
draft.shift()
// 删除指定位置的元素
draft.splice(0, 1)
// 根据条件删除元素
const index = draft.findIndex(todo => todo.id === 2)
if (index !== -1) {
draft.splice(index, 1)
}
})修改元素
javascript
const todos = [
{ id: 1, text: "学习 Immer", done: false },
{ id: 2, text: "构建应用", done: false }
]
const newTodos = produce(todos, draft => {
// 修改指定索引的元素
draft[0].done = true
// 根据条件修改元素
const todo = draft.find(todo => todo.id === 2)
if (todo) {
todo.text = "构建更好的应用"
}
// 修改所有元素
draft.forEach(todo => {
todo.updatedAt = new Date().toISOString()
})
})排序和反转
javascript
const todos = [
{ id: 3, text: "编写文档", done: false },
{ id: 1, text: "学习 Immer", done: true },
{ id: 2, text: "构建应用", done: false }
]
const newTodos = produce(todos, draft => {
// 排序
draft.sort((a, b) => a.id - b.id)
// 反转
draft.reverse()
})注意事项
- 使用
map、filter、reduce等方法时,它们会返回新的数组,而不是修改原数组。你需要将结果赋值回 draft:
javascript
const todos = [
{ id: 1, text: "学习 Immer", done: false },
{ id: 2, text: "构建应用", done: false },
{ id: 3, text: "编写文档", done: false }
]
const newTodos = produce(todos, draft => {
// 使用 filter 过滤元素
draft.splice(0, draft.length, ...draft.filter(todo => !todo.done))
// 使用 map 转换元素
draft.splice(0, draft.length, ...draft.map(todo => ({
...todo,
done: false
})))
})- 只有数值属性和
length属性会被保留在数组上,自定义属性不会被保留。