This commit is contained in:
2026-04-26 16:50:53 +08:00
parent ea33413187
commit 705a2d3dd8
30 changed files with 1537 additions and 570 deletions

View File

@@ -0,0 +1,45 @@
# 冒险实体详情 NPC 预览修复记录2026-04-26
## 背景
RPG 运行态点击画面中的对面 NPC 角色形象时,详情弹窗的立绘与画布上实际显示的 NPC 不一致,并伴随 React 报错:
`Encountered two children with the same key, ``.`
## 问题定位
1. 画布层 `GameCanvasEntityLayer` 渲染 NPC 时,会优先使用当前 `Encounter` 实例上的 `visual``imageSrc``monsterPresetId`,再回退到 `characterId` 对应的预设角色。
2. 详情弹窗 `AdventureEntityModal` 原本优先按 `characterId` 渲染预设角色,导致运行时遭遇已经携带独立形象时,点击后弹窗显示成另一个角色内容。
3. `AdventureEntityModal` 内部存在多个浮层共用同一个 `AnimatePresence`,直系子节点没有显式稳定 key同时 NPC 运行时背包物品如果传入空 `id`,会把空字符串直接交给物品格列表作为 React key。
## 落地约束
1. NPC 详情立绘必须与画布点击对象一致:
- `encounter.visual`
- `encounter.imageSrc`
- `encounter.monsterPresetId`
- `encounter.characterId`
- 通用 NPC 生成形象
2. 前端只做展示优先级和 key 稳定性处理,不新增剧情规则、不改写运行时 NPC 数据来源。
3. 所有列表和并列浮层都必须具备稳定、非空、可区分的渲染 key。
## 本次修改
1. `src/components/AdventureEntityModal.tsx`
- 新增 `NpcEncounterPortrait`,让弹窗立绘优先使用遭遇实例形象,与画布渲染策略对齐。
- 新增 `selectionRenderKey`,给实体详情、标签详情、技能详情浮层提供稳定 key。
- 新增 NPC 背包物品渲染 id 规范化,避免空 id 或重复 id 触发 React key 冲突,并避免点击物品时选中错误项。
- 技能附带状态标签 key 增加兜底字段,避免空 buff id 冲突。
2. `src/components/AdventureEntityModal.test.tsx`
- 覆盖“有 `characterId` 但遭遇实例提供 `imageSrc` 时,详情立绘必须显示遭遇图像”。
- 覆盖“NPC 背包物品空 id 不再触发重复 key 警告”。
## 验证
已执行:
```bash
npm run test -- AdventureEntityModal.test.tsx CharacterInfoShared.test.tsx
```
结果5 个测试全部通过。