用户目录中的用户统计信息不正确

这最终变成了一个棘手的“竞态条件”,发生在用于检测何时需要触发“加载更多”操作的“哨兵”与用户目录中行的渲染之间 :exploding_head:

问题

当用户数量至少为 50 时,“/u”(用户目录)页面会在用户向下滚动之前立即触发 loadMore。这会导致意外地自动加载第二页结果。

根本原因

初始页面加载期间的竞态条件:

  1. 用户导航到 /u
  2. controllers/users 开始加载数据 (isLoading: true)
  3. 模板渲染 ConditionalLoadingSpinner 并显示加载指示器
  4. 数据到达,isLoading 变为 false
  5. 加载指示器隐藏,DirectoryTable 开始渲染 50 个用户
  6. LoadMore 哨兵元素插入 DOM
  7. IntersectionObserver 被创建并立即开始观察
  8. 此时,表格仍在计算布局/扩展到完整高度
  9. 在表格扩展之前,哨兵短暂地出现在视口中(距离顶部约 292px)
  10. 观察者检测到交叉 → 触发 loadMore :cross_mark:
  11. 表格完成扩展到完整高度(约 3689px)
  12. 哨兵移动到正确位置(约 3959px,视口下方)

观察者“过于积极”——它在内容完成布局之前就开始观察,在表格尚未达到最终高度的短暂时刻捕获了哨兵。

修复

延迟创建观察者,直到内容准备就绪:

LoadMore 添加了一个 @isLoading 参数,当内容仍在加载时,该参数会阻止创建 IntersectionObserver

现在的工作方式

页面加载 → isLoading=true → Modifier 跳过观察者创建
             ↓
数据加载 → isLoading=false → Modifier 重新运行,创建观察者
             ↓
表格完全展开 → 哨兵位于正确位置(视口下方)
             ↓
用户向下滚动 → 哨兵进入视口 → loadMore 触发 ✓

5 个赞