You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React报错:子元素key重复,使用useContext后出现该问题

问题解决笔记:React笔记应用重复key问题

核心问题分析

  1. ID生成逻辑错误:你在App组件外部只调用了一次uuid()生成small_id,所有初始笔记和新增笔记都复用这个ID,直接导致React列表渲染时的key完全重复,这是根本原因,和useContext无关。
  2. useContext未正确使用:你改用Context传递addHandleNote后,AddNote组件仍然在尝试通过props接收这个函数,根本没从Context里拿值,等于白改了Context。

分步修复

1. 修复ID生成逻辑

修改App.js,确保每个笔记都有唯一ID:

  • 初始笔记的每个对象单独生成ID
  • 新增笔记时,每次都生成新的ID

修改后的App.js关键部分:

import { useState } from "react";
import { v4 as uuid } from "uuid";
import NotesList from "./components/NotesList";
import HandleAddContext from "./components/UseContext/HandleAddContext";

// 生成单个短ID的工具函数
const generateSmallId = () => uuid().slice(0, 8);

// 初始状态每个笔记用独立ID
const initialState = [
  {
    id: generateSmallId(),
    text: "1st note",
    date: "12/10/2022",
  },
  {
    id: generateSmallId(),
    text: "2nd note",
    date: "15/10/2022",
  },
  {
    id: generateSmallId(),
    text: "3rd note",
    date: "16/10/2022",
  },
  {
    id: generateSmallId(),
    text: "4th note",
    date: "30/10/2022",
  },
];

export const App = () => {
  const [notes, setNotes] = useState(initialState); // 变量名修正:setNote → setNotes,更语义化

  const addHandleNote = (text) => {
    const date = new Date();
    const newNote = {
      id: generateSmallId(), // 每次新增都生成新ID
      text: text,
      date: date.toLocaleDateString(),
    };
    const newNotes = [...notes, newNote];
    setNotes(newNotes);
  };

  return (
    <HandleAddContext.Provider value={addHandleNote}>
      <div className="container">
        <NotesList notes={notes} />
      </div>
    </HandleAddContext.Provider>
  );
};

export default App;

2. 修复AddNote的Context消费逻辑

修改AddNote.js,用useContext获取addHandleNote,不再依赖props:

import { useState, useContext } from "react"; // 导入useContext
import { RiSave2Line } from "react-icons/ri";
import HandleAddContext from "./UseContext/HandleAddContext"; // 导入Context

const AddNote = () => { // 移除props参数
  const [addText, setAddText] = useState("");
  const [errorMsg, setErrorMsg] = useState("");
  const handleAddNote = useContext(HandleAddContext); // 从Context获取函数

  const handleChange = (e) => {
    setAddText(e.target.value);
  };

  const handleSaveClick = () => {
    if (addText.trim().length > 0) {
      handleAddNote(addText);
    }  
  };

  return (
    <div>
      <textarea
        rows="8"
        cols="10"
        placeholder="Type here to add a note..."
        value={addText}
        onChange={handleChange}
      />

      <div>
        <p>200 characters remaining</p>
        <RiSave2Line onClick={handleSaveClick} />
      </div>
    </div>
  );
};

export default AddNote;

3. 其他小修正

  • NotesList里不需要给AddNote传props了,保持现有代码即可
  • 初始状态里的日期写错了,22022改成2022(可选,不影响功能但更合理)

验证效果

修改后,每个笔记都会有唯一的ID,React列表渲染的key不再重复,同时AddNote也能正确通过Context调用添加笔记的函数,问题解决。

内容的提问来源于stack exchange,提问作者N S

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 01:16:08