Pressidian
花园入口
笔记
项目
关于
实验室
GitHub
花园入口
笔记
项目
关于
实验室
GitHub

KNOWLEDGE PATHS

笔记库
当前位置
笔记库/前端/项目笔记/代达罗斯/考试/2026-07-30-Finding反馈交互

EXAM-20260730-01:Finding 反馈交互链路

7 分钟阅读 · Note

目录树 578 篇

              • EXAM-20260730-01 阅卷报告:Finding 反馈交互链路
              • EXAM-20260730-01:Finding 反馈交互链路
            • 代达罗斯前端考试索引
            • 前端能力画像
            • 深色模式
            • 阅卷报告:CrateDetailPageContent
            • 阅卷报告:ThemeProvider.tsx(第二次)
            • CrateDialog
          • 项目待做
          • 性能优化
          • UI设计
      • 前端技术栈
    • 笔记目录
    • CLAUDE.md
    • Vue 组件与 Render 函数

关联笔记 6

↗EXAM-20260730-01 阅卷报告:Finding 反馈交互链路同一路径↗深色模式共同主题↗阅卷报告:CrateDetailPageContent共同主题↗阅卷报告:ThemeProvider.tsx(第二次)共同主题↗CrateDialog共同主题↗EXAM-20260730-02 答辩与现场接管记录共同主题
  • EXAM-20260730-01:Finding 反馈交互链路

EXAM-20260730-01:Finding 反馈交互链路

本次选题依据

  • 薄弱程度(主要依据):能力画像中“事件冒泡与复合交互边界”为 40%、“JSX 信息完整性与异步分支”为 60%,均低于 70%。
  • 重复错误:最近一次答卷中行内按钮冒泡导致“归档并导航”同时发生;mutation payload 也再次出现把对象写成字符串的问题。
  • 复习紧迫度:上述薄弱项下一次复习日为 2026-08-02,已进入最近复习窗口;本次用 Finding 反馈场景做变式复测,不复刻原题。
  • 项目相关性:所选三个文件存在真实 Hook → 反馈按钮 → Rule 详情页 调用关系,覆盖当前项目的 React Query、tRPC 客户端、Refine mutation 与可点击行交互。
  • 新旧知识占比:事件边界、早返回、异步分支与 payload 边界属于历史复测;React Query 精确缓存失效是本次扩展,新知识不超过主题一半。
  • 难度与提示强度:中等;重复错误项减少一层直接提示,但仍明确变量、API、数据流和自检行为。

文件顺序与数据流

  1. use-finding-feedback.ts:封装单条反馈查询、反馈提交和缓存失效,向组件暴露 feedback/isPending/error/submit。
  2. finding-feedback-buttons.tsx:消费 Hook,提供三种反馈按钮,并隔离父级行点击事件。
  3. RuleDetailPageContent.tsx:加载规则关联的 Findings,把每条记录组合成可展开行并嵌入反馈按钮。

数据流:RuleDetailPageContent Finding → FeedbackButtons Props → useFindingFeedback query/mutation → 缓存失效 → UI 高亮/列表刷新

推荐按第 1 → 8 题顺序作答。整卷只包含前端 Hook、组件和页面内容组件,不含 tRPC router、Service、DAO、数据库或服务端认证题目。

源文件与基准

  • Git 基准提交:4e03802a81989b0ae6da6ca775d9fa789a93e773
  • G:\Save\Grogramming\CodexWorkTree\ab1e\daedalus\apps\app\src\hooks\use-finding-feedback.ts
  • G:\Save\Grogramming\CodexWorkTree\ab1e\daedalus\apps\app\src\components\finding-feedback-buttons.tsx
  • G:\Save\Grogramming\CodexWorkTree\ab1e\daedalus\apps\app\src\pages\RuleDetailPage\RuleDetailPageContent.tsx

第1题(文件 1/3):读取单条 Finding 的反馈状态

  • 上下文:FeedbackButtons 会消费本 Hook 返回的 feedback,用它高亮当前选择。
  • 目标:按 findingId 查询反馈;没有记录或请求失败时,页面仍能以“未选择”状态继续渲染。
  • 已知:findingId 来自父组件 Props;trpcClient 已提供 getFeedbackByFinding.query。
  • 产出:声明 const { data },供文件末尾的 feedback 派生值使用。
  • 实现路线:用 findingId 组成稳定 queryKey;在 queryFn 调用接口并把失败收敛为 null;空 id 时禁止查询。
  • 边界:空 findingId 不应请求;查不到或查询失败不能阻断按钮渲染。
  • 可用 API:useQuery、trpcClient.findings.getFeedbackByFinding.query、enabled。
  • 自检:同一 id 复用缓存;切换 id 读取另一条记录;空 id 不请求。

第2题(文件 1/3):提交反馈并精确失效缓存

  • 上下文:文件 2 的三个按钮会调用 submit;成功后按钮自身和上层 Findings 列表都要刷新。
  • 目标:提交合法 outcome payload,暴露 pending/error,并在成功后刷新两级缓存与通知父级。
  • 已知:findingId、runId、queryClient、options;outcome 只允许 accepted/rejected/ignored。
  • 产出:声明 const { mutate, isPending, error },供 Hook 返回对象使用。
  • 实现路线:mutationFn 组合三个 payload 字段;成功后依次失效单条反馈和 Findings 列表缓存;最后安全调用可选回调。
  • 边界:不能只传 outcome 字符串;可选回调不存在时不能报错。
  • 可用 API:useMutation、queryClient.invalidateQueries、options?.onSuccess?.()。
  • 自检:提交期间 pending;成功后高亮刷新;上层列表可感知变化。

第3题(文件 2/3):隔离行内按钮事件并防止重复提交

  • 上下文:本组件放在文件 3 的可点击 Finding 行中;按钮点击不能继续冒泡触发行展开。
  • 目标:三个回调分别提交对应 outcome,并在请求进行中忽略重复点击。
  • 已知:submit 来自第2题;isPending 表示请求进行中;事件为 React.MouseEvent。
  • 产出:完成 handleAccept、handleReject、handleIgnore 三个稳定回调。
  • 实现路线:先阻止冒泡;非 pending 时提交对应值;依赖数组覆盖外部读取值。
  • 边界:pending 时仍需阻止冒泡;三个 outcome 不得错位。
  • 可用 API:event.stopPropagation()、submit、useCallback。
  • 自检:按钮不展开/收起父行;快速连点不重复提交;三按钮值不同。

第4题(文件 2/3):把反馈按钮接到三个事件回调

  • 上下文:第3题已建立事件边界;JSX 负责把三枚按钮接到正确回调。
  • 目标:每个按钮提交与图标/文案一致的反馈,同时保留现有高亮与可访问名称。
  • 已知:三个 handle 回调;现有 aria-label、className、type 与子节点全部保留。
  • 产出:为三枚 button 分别补上正确点击属性。
  • 实现路线:按语义逐一映射;不改 active class;传函数引用。
  • 边界:不要写成立即调用表达式;不要交换 reject 与 ignore。
  • 可用 API:button 的 onClick。
  • 自检:三个按钮各触发正确回调;当前 outcome 高亮仍正常;按钮名称可读。

第5题(文件 3/3):按规则身份加载 Findings

  • 上下文:路由 id 决定当前 Rule;结果进入页面底部异步列表并传给文件 2。
  • 目标:规则变化时加载对应 Findings,请求结束后关闭 loading。
  • 已知:id、两个 setter、trpcClient.findings.listByRuleId.query。
  • 产出:一个依赖规则 id 的 useEffect。
  • 实现路线:请求前打开 loading;以 { ruleId } 查询并写入数组;无论成功失败都关闭 loading。
  • 边界:依赖必须包含 id;payload 字段是 ruleId,不能传裸字符串。
  • 可用 API:useEffect、Promise.then、Promise.finally。
  • 自检:首次进入显示加载;切换规则重新请求;失败后不会永久 loading。

第6题(文件 3/3):守住规则开关的 mutation 边界

  • 上下文:页面右上角 Switch 调用回调;rule 尚未加载时不能构造更新请求。
  • 目标:有 rule 时反转 enabled 并提交 Refine update;没有 rule 时立即结束。
  • 已知:rule、id、updateRule、ResourceName.rules。
  • 产出:完成 handleToggleRule 函数体,保持依赖完整。
  • 实现路线:先做失败路径早返回;组装 resource/id/values;enabled 取反。
  • 边界:早返回后不能继续 mutation;values 必须为对象;不原地修改 rule。
  • 可用 API:updateRule({ resource, id, values })、useCallback。
  • 自检:加载前不请求;开关双向切换;其他字段不变。

第7题(文件 3/3):补齐 Findings 的异步三态骨架

  • 上下文:第5题维护 loading 和数组;数据列表的内部 JSX 已完整保留。
  • 目标:按 loading → empty → data 的互斥顺序渲染,避免加载时闪出空态。
  • 已知:findingsLoading、findings、Loader2、EmptyState 与现成列表。
  • 产出:把列表包进条件渲染,补加载节点和空状态。
  • 实现路线:先判断 loading;再判断长度为 0;否则显示列表。
  • 边界:加载中的空数组不能显示 EmptyState;分支互斥。
  • 可用 API:三元表达式、Loader2、EmptyState。
  • 自检:请求中只见 spinner;完成且为空只见空态;有数据才见列表。

第8题(文件 3/3):组合可展开行与反馈子组件

  • 上下文:整行点击负责展开详情;文件 2 的按钮负责提交反馈并阻止冒泡。
  • 目标:恢复行点击展开,并在反馈区域传入当前 finding/run 身份。
  • 已知:f、handleToggleExpand、FeedbackButtons;findingId 需字符串,runId 可回退空串。
  • 产出:行容器的 onClick,以及 FeedbackButtons 的两个身份 Props。
  • 实现路线:行点击传 f.id;反馈组件收到两个 id;依赖第3题隔离事件。
  • 边界:不要在渲染时立即调用回调;缺少 runId 时传安全字符串。
  • 可用 API:onClick、String(f.id)、空值合并运算符。
  • 自检:点行展开;点反馈按钮不折叠;每行提交自己的 id。

出题验证结果

  • Git 状态:出题前工作树干净;三个目标文件均已被 Git 跟踪。
  • 依赖关系:已确认 RuleDetailPageContent 导入 FeedbackButtons,后者导入 useFindingFeedback。
  • 安全边界:未选择 tRPC router、Service、DAO、数据库、服务端路由或认证文件作为答题文件。
  • 差异检查:imports、顶层类型/常量、export 名称与函数签名均保留;全局题号 1–8 连续且无重复。
  • JSX 规则:保留列表与按钮的大部分既有结构,只移除三态外壳、事件绑定和子组件接线。
  • 格式检查:git diff --check 无空白错误,仅有工作树既有的 LF/CRLF 提示。
  • 质量检查:未运行全量 typecheck/lint/test,因为挖空变量与回调会按预期阻断静态检查。