0%

已完成 0/29 关

教学模式

你可以随时调整。

此设置调整教师的教学方式,无需重新生成课程。

第 19 关 含代码 含表格 约 10 分钟

更新 State 中的数组:添加、删除、替换与排序

更新 State 中的数组:添加、删除、替换与排序

数组是 JavaScript 中最灵活、最重要的数据结构之一。在 React 中,你经常需要将数组保存在 State 中:购物车列表、聊天消息流、待办事项清单。

就像普通对象一样,保存在 React State 中的数组也是只读的。你不应该直接调用 arr[0] = '新值',也不应该调用 push()、pop()、splice() 这类会直接变异原数组的方法。


1. 数组操作方法对照表:变异 vs 返回新数组

为了在 React 中优雅地更新数组,你需要掌握以下方法转换表:

操作需求❌ 变异原数组(切勿在 React 中使用)✅ 返回全新数组(推荐在 React 中使用)
添加元素push()、unshift()展开语法 [...arr, newItem]
删除元素pop()、shift()、splice()filter()、slice()
修改/替换元素arr[i] = ...、splice()map() 映射
重新排序sort()、reverse()先拷贝再排序 [...arr].sort()

2. 向数组中添加元素

使用数组展开语法 [...arr] 创建一个新数组,并在末尾或开头插入新项:

import { useState } from 'react';

let nextId = 0;

export default function List() {
  const [name, setName] = useState('');
  const [artists, setArtists] = useState([]);

  function handleClick() {
    setArtists([
      ...artists, // 包含旧的所有艺术家
      { id: nextId++, name: name } // 在末尾追加新人
    ]);
  }

  return (
    <>
      <h1>著名雕塑家名单</h1>
      <input
        value={name}
        onChange={e => setName(e.target.value)}
      />
      <button onClick={handleClick}>添加</button>
      <ul>
        {artists.map(artist => (
          <li key={artist.id}>{artist.name}</li>
        ))}
      </ul>
    </>
  );
}

如果希望添加到列表最开头,只需颠倒顺序:[{ id: nextId++, name: name }, ...artists]。


3. 从数组中删除元素

从数组中删除某一项的最佳方式,是使用 filter() 方法——过滤掉那个不需要的项,保留剩下的所有项返回一个新数组:

function handleDelete(id) {
  setArtists(
    artists.filter(artist => artist.id !== id)
  );
}

在这里,artist.id !== id 意味着:“只要这个人的 ID 不等于我想删除的 ID,他就留下来”。被点击的那个对象就会自然被剔除在返回的新数组之外!


4. 转换与修改数组中的元素

当你需要修改数组中的某个特定元素(例如把 ID 为 3 的待办事项标记为“已完成”),请使用 map():

function handleToggleTodo(id) {
  setTodos(
    todos.map(todo => {
      if (todo.id === id) {
        // 创建一个全新的对象,覆盖 done 属性
        return { ...todo, done: !todo.done };
      } else {
        // 没有发生改变的其他项原样保留
        return todo;
      }
    })
  );
}

map() 会遍历每一项,当遇到要修改的那项时,返回一份拷贝了现有数据并修改了个别字段的全新对象;其余项则不受影响直接返回。


5. 对数组进行排序或反转

JavaScript 原生的 sort() 和 reverse() 是会直接修改原数组的。 如果你直接写 artists.sort(),你就变异了 State 中的原有数据!

正确的做法是:先用展开语法拷贝一份新数组,然后再对新数组进行排序:

function handleSort() {
  // 1. 先用 [...list] 浅拷贝一份独立的全新数组
  const nextList = [...list];
  // 2. 在新数组上调用 sort()
  nextList.sort((a, b) => a.title.localeCompare(b.title));
  // 3. 把排序后的新数组传给 setState
  setList(nextList);
}

总结

  • 数组也是对象,切勿在 React State 中调用 push、splice 或通过索引直接赋值;
  • 使用 [...arr, item] 添加新元素;
  • 使用 arr.filter(item => item.id !== id) 删除特定元素;
  • 使用 arr.map(item => item.id === id ? { ...item, ...updates } : item) 优雅修改单项;
  • 使用 [...arr].sort() 安全地先拷贝再排序。
下一站:用 State 响应输入:从声明式视角重塑 UI 状态机 →
© 2026 React 官方教程