Files
Genarrative/docs/technical/ADVENTURE_ENTITY_MODAL_NPC_PREVIEW_FIX_2026-04-26.md
2026-04-26 16:50:53 +08:00

2.2 KiB
Raw Blame History

冒险实体详情 NPC 预览修复记录2026-04-26

背景

RPG 运行态点击画面中的对面 NPC 角色形象时,详情弹窗的立绘与画布上实际显示的 NPC 不一致,并伴随 React 报错:

Encountered two children with the same key, ``.

问题定位

  1. 画布层 GameCanvasEntityLayer 渲染 NPC 时,会优先使用当前 Encounter 实例上的 visualimageSrcmonsterPresetId,再回退到 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 警告”。

验证

已执行:

npm run test -- AdventureEntityModal.test.tsx CharacterInfoShared.test.tsx

结果5 个测试全部通过。