为什么 React 中的 key 不能用索引?

大家好,我是 前端架构师 - 大卫

关注微信公众号 @程序员大卫 ,回复 [资料] 即可领取前端精品资料包。

前言

在 React 中,React 自身无法自动生成合适的 key。 只有你(开发者)最清楚你的数据结构,也只有你知道:在两次渲染之间,哪些元素是"相同"的(哪怕内容有变),哪些元素又是"全新的"。

通常情况下,key 应该来自数据本身,例如数据库中的唯一 ID、对象的唯一标识符等,而不应该使用数组的索引或随机数。

示例

来看一个简单的例子:

当我们删除 b 这一项时,预期渲染结果应该是:

css 复制代码
a
c

但实际结果却成了:

css 复制代码
a
b

问题出在哪?看一下代码:

js 复制代码
import { useState } from "react";
import "./App.css";

function App() {
  const [list, setList] = useState(["a", "b", "c"]);

  const handleDelete = (index) => {
    list.splice(index, 1);
    setList([...list]);
  };

  return (
    <div className="App">
      {list.map((item, index) => (
        <div key={index}>
          <input defaultValue={item} />
          <button onClick={() => handleDelete(index)}>Delete</button>
        </div>
      ))}
    </div>
  );
}

export default App;

问题的本质:索引不是稳定的 key

当你使用数组索引作为 key 时,元素位置一旦变化,React 会错误地认为组件"没变",于是继续复用旧的组件实例。

这导致本该删除或更新的节点没有被正确识别和替换,进而引发各种渲染问题(例如输入框错位、删除异常等)。

如果你使用随机 key 会怎样?

如果你改成这样:

js 复制代码
<div key={Math.random()}>

React 会认为:"每次渲染,这些节点全都是全新的。" 于是它会:

  • 销毁所有旧组件;
  • 重新创建新的组件;
  • 丢失所有组件内部状态(比如输入框的光标、临时值等)。

这样做虽然能"避免"索引问题,但也彻底失去了 React 高效更新的核心优势。 每次渲染都像"重建整棵树"一样,没有任何性能可言。

总结

在 React 中:

  • key 应该是数据层面的唯一标识(如 ID、UUID、唯一名称);
  • 不要使用数组索引或随机数作为 key;
  • key 的作用是帮助 React 找到前后渲染中相同的元素,从而实现高效更新。

记住一句话:

React 不在乎你渲染了什么,而在乎的是:哪些东西变了,哪些没变。

相关推荐
Rust研习社18 小时前
使用 Axum 构建高性能异步 Web 服务
开发语言·前端·网络·后端·http·rust
C澒18 小时前
AI 生码 - API2Code:接口智能匹配与 API 自动化生码全链路设计
前端·低代码·ai编程
浔川python社19 小时前
HTML头部元信息避坑指南技术文章大纲
前端·html
IT_陈寒19 小时前
SpringBoot配置加载顺序把我坑惨了
前端·人工智能·后端
kyriewen19 小时前
Next.js部署:从本地跑得欢,到线上飞得稳
前端·react.js·next.js
Moment19 小时前
面试官:给 llm 传递上下文,有哪几个身份 role ❓❓❓
前端·后端·面试
跨境数据猎手19 小时前
跨境独立站系统技术拆解(附带源码)
服务器·前端·php
豹哥学前端19 小时前
用猜数字游戏,一口气掌握 JavaScript 核心知识点(附完整代码)
前端·javascript
忆往wu前20 小时前
从0到1一步步拆解搭建,梳理一个 Vue3 简易图书后台全开发流程
前端·javascript·vue.js
木斯佳20 小时前
前端八股文面经大全:字节抖音前端三面(2026-04-27)·面经深度解析
前端·面试·笔试·八股·面经