diff --git a/docs/BUG_HISTORY.md b/docs/BUG_HISTORY.md index 3130cc4c..3013016a 100644 --- a/docs/BUG_HISTORY.md +++ b/docs/BUG_HISTORY.md @@ -5579,6 +5579,22 @@ - 复发自:BUG-375(区分卡已落到剩余分钟,但题型仍是存在性,选题顺序仍写死) - 修复版本:待发布 +## BUG-383 | 点选卡开关在 render 里写 ref,staging ESLint 失败 + +- 状态:resolved +- 首次发现:2026-08-25 +- 最近更新:2026-08-25 +- 影响面:Gitea `backend-quality-gate` 的 `npm run lint --prefix frontend`、`frontend/src/components/rectification-agentic-chat.tsx` +- 用户现象:向 `staging` 推送 `f5e73ef3` 后 quality gate run `2073` 失败。`validate` job `5170` 前端测试 2042/2042 通过,随后 lint `✖ 17 problems (1 error, 16 warnings)`。`publish` job `5171` 因 `needs: validate` 跳过。 +- 触发条件:含 BUG-381「回到最新」避让点选卡的提交进入完整 `xiaoxin` runner 的 frontend lint。 +- 根因:`react-hooks/refs` 禁止在 render 期间更新 `ref.current`。BUG-381 用 `choiceCardsOpen.current = showChoiceCards` 给滚动回调最新点选卡开关,写在 render 里。父提交 `7a4360d8` 的 run `2072` 已因同一行失败。 +- 修复:把 ref 写入现有 `useLayoutEffect`,再调用 `updateFollowState`。不改 Skill `10.0.11`。 +- 验证:`npx eslint src/components/rectification-agentic-chat.tsx`;`frontend/tests/rectification-agentic-entry.test.ts`。 +- 防复发:点选卡可见状态不得在 render 里写 `ref.current`;源码合同锁定该赋值只出现在 layout effect。 +- 相关记录:BUG-326、BUG-381 +- 复发自:BUG-326(窄屏盘面 `onCloseRef.current = onClose` 同样在 render 里写 ref) +- 修复版本:待发布 + ## BUG-379 | 生时纠正已记入学后仍编造高考年并再问入学 - 状态:resolved diff --git a/frontend/src/components/rectification-agentic-chat.tsx b/frontend/src/components/rectification-agentic-chat.tsx index 3eb2699f..9ac7dfcb 100644 --- a/frontend/src/components/rectification-agentic-chat.tsx +++ b/frontend/src/components/rectification-agentic-chat.tsx @@ -983,8 +983,8 @@ export function RectificationAgenticChat(props: RectificationAgenticChatProps) { && !readonly && regeneratingMessageKey === null, ); - choiceCardsOpen.current = showChoiceCards; useLayoutEffect(() => { + choiceCardsOpen.current = showChoiceCards; updateFollowState(); }, [showChoiceCards, updateFollowState]); const showSelectionCards = Boolean( diff --git a/frontend/tests/rectification-agentic-entry.test.ts b/frontend/tests/rectification-agentic-entry.test.ts index db590539..88acd185 100644 --- a/frontend/tests/rectification-agentic-entry.test.ts +++ b/frontend/tests/rectification-agentic-entry.test.ts @@ -278,6 +278,11 @@ test("Agentic rectification follows the conversation tail only while the reader assert.match(chat, /top: viewport\.scrollHeight/); assert.match(chat, /shouldShowJumpToLatest/); assert.match(chat, /choiceCardsOpen/); + assert.match( + chat, + /useLayoutEffect\(\(\) => \{\s*choiceCardsOpen\.current = showChoiceCards;\s*updateFollowState\(\);\s*\}, \[showChoiceCards, updateFollowState\]\)/, + ); + assert.doesNotMatch(chat, /choiceCardsOpen\.current = showChoiceCards;\s*useLayoutEffect/); assert.match(chat, /updateFollowState/); assert.match(chat, /\}, \[busy, candidateResult, choiceCard, error, messages, savedTime, followLatestContent\]\);/); assert.match(styles, /\.rectification-jump-latest \{[\s\S]*justify-content: flex-end/);