修复资源替换弹窗初始化竞态

将弹窗打开态初始化改为 useLayoutEffect,避免素材选择被异步初始化清空
补充资源选择弹窗竞态的排障记录与定向验证命令
This commit is contained in:
2026-09-13 11:44:27 +00:00
parent 340d8241a5
commit 6149aaf5f6
2 changed files with 11 additions and 2 deletions
@@ -653,6 +653,13 @@ Cocos Creator 根目录由 `package.json.creator.version` 与普通 `assets/`
- 验证:先精确运行目标用例,再以默认并行度重复运行完整 crate;失败类测试同时执行时,各实例目录只能包含自己的输入 / 输出日志,测试结束后临时目录必须清理。
- 关联:`server-rs/crates/platform-llm/src/lib.rs``server-rs/crates/api-server/src/creation_agent_llm_turn.rs``server-rs/crates/api-server/src/custom_world_foundation_draft.rs`
## 素材选择弹窗的打开初始化必须先于用户点击
- 现象:版本级资源替换用例偶发在确认后读不到替换关系;本地单独运行通过,完整前端回归或 CI 中失败。
- 原因:弹窗打开时用普通 `useEffect` 初始化选择,用户点击素材可能先提交 `setSelection`,随后初始化 effect 又把选择清空,确认收到空数组而不会发起写入。
- 处理:初始化查询、分类和选择改用 `useLayoutEffect`,仍只依赖 `open`,在首次绘制前完成打开态初始化,避免父级普通重渲染重置用户选择。
- 验证:`npm test -- apps/ai-game-creator-shell/tests/resourceVersionReplacement.test.tsx --reporter=dot`;应通过该文件全部 16 条用例。
## 带 objectKey 的画布图片测试要等待换签后可见
- 现象:测试点击“添加素材”后,图层状态已经写入,但立即用 `getByAltText('画布图片:...')` 偶发或稳定找不到图片;前一张图可能通过,紧接着添加的第二张失败。
@@ -1,5 +1,5 @@
import { Check, ImageIcon, Music, Search, Video } from 'lucide-react';
import { type ReactNode, useEffect, useMemo, useState } from 'react';
import { type ReactNode, useLayoutEffect, useMemo, useState } from 'react';
import { PlatformActionButton } from '../../../packages/shared/src/components/PlatformActionButton';
import { PlatformResourceFilterBar } from '../../../packages/shared/src/components/PlatformResourceFilterBar';
@@ -133,7 +133,9 @@ export function ImageCanvasProjectAssetPickerDialog({
// `useImageCanvasGenerationSurface` 里是即时 `.filter().flatMap()`),把它放进依赖
// 会让「父级任何一次重渲染」都重新清空搜索词、分类与在选中的选择。
// `open` 翻成 true 的那一帧本身已经带着最新的初始选择,读到的就是它。
useEffect(() => {
// 用 layout effect 在首次绘制前完成初始化,避免用户在初始化 effect 执行前点击素材,
// 随后又被初始化逻辑清空选择。
useLayoutEffect(() => {
if (!open) return;
setQuery('');
setCategory('all');