AGENTS.md@frontend/packages/react · git:20261104.0b713a5 · 2026-11-04 · sha256 dbd69acc6692fee3
AGENTS.md@frontend/packages/react git:20261104.0b713a5A
Immutable. This exact content never changes and is served at /api/v1/blob/dbd69acc6692fee3.
# React Agent Guide 适用于 `frontend/packages/react/**`,同时遵循 [Frontend Agent Guide](../../AGENTS.md) 和更深目录的规则。 ## useEffect 使用门槛 - 新增或修改组件、自定义 Hook 时,非必要不使用 `useEffect`。只有需要在渲染提交后,将组件与明确的外部系统保持同步,且更直接的声明式 API、事件处理或已有专用 Hook 无法满足时,才允许使用。 - 外部系统包括浏览器订阅、非 React 控件和网络服务;组件内部的 props、state 及其派生值不是外部系统。“挂载后执行”“依赖变化时执行”或“只运行一次”本身不能证明必要性。 - 不得通过改名、封装自定义 Hook 或替换为 `useLayoutEffect` 绕过本规则。按 React 官方的 [You Might Not Need an Effect](https://react.dev/learn/you-might-not-need-an-effect) 判断是否可以移除 Effect。 ## 优先选择替代方式 | 场景 | 应采用的方式 | | ---------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | | 根据 props/state 计算文案、过滤结果或选中项 | 渲染时直接计算;仅在确有性能需要时用 `useMemo`,不另存 state 再用 Effect 同步 | | 点击、提交、删除等用户操作,以及由此触发的请求、通知或父组件回调 | 在对应事件处理器中执行,必要时提取共享函数;不通过 state 标记再由 Effect 接力执行 | | props 改变后重置状态,或同步父子组件状态 | 优先使用受控状态、提升状态;身份变化需要重置整个子树时使用 `key` | | 订阅外部可读状态,如 Store 或浏览器在线状态 | 优先复用订阅 API,或使用 [`useSyncExternalStore`](https://react.dev/reference/react/useSyncExternalStore),不手写 Effect 镜像状态 | 数据获取优先复用宿主、框架或已有数据层能力。业务模块 Hook 或宿主数据层确需随当前查询参数同步服务端结果时,可以使用 Effect;不能一概改成点击事件,否则 URL 导航等变化可能漏取数据。遵守分层边界:`components/` 及其私有 Hook 仍不得取数或创建业务连接。 ## 每个 Effect 必须说明必要性 在每一个实际 `useEffect` 调用的紧邻上方添加注释;自定义 Hook 内的调用也不例外。注释必须回答: 1. 正在与哪个具体外部系统同步,哪些输入决定同步内容? 2. 为什么不能通过渲染计算、事件处理或已有专用 API 完成,必须由 Effect 随组件保持同步? 3. 依赖变化或卸载时如何清理、撤销或使旧结果失效?无需清理时说明原因。 例如,为需要持续响应容器尺寸变化的视图添加订阅时: ```ts // useEffect 必要性:用 ResizeObserver 订阅当前容器的尺寸; // DOM 节点提交后才可订阅,且尺寸也会因外部布局变化,不能只在点击事件中更新。 // 容器更换或组件卸载时 disconnect,避免旧订阅继续回调。 ``` 仅写“初始化”“监听变化”“同步状态”或“避免重复执行”不满足要求。 ## 必要 Effect 的实现要求 - 按 [`useEffect` 官方约定](https://react.dev/reference/react/useEffect) 声明完整依赖;不得靠省略依赖或关闭 Hooks lint 消除重跑。 - 按 [Synchronizing with Effects](https://react.dev/learn/synchronizing-with-effects) 对称地建立和清理订阅、连接、定时器等资源;异步请求取消或忽略过期结果,避免旧结果覆盖新状态。 - 保证开发环境 Strict Mode 的建立、清理、再建立过程正确;不得用“只执行一次”的 ref 标记或全局变量掩盖缺失清理的问题。 - 浏览器 API 在客户端的必要阶段访问,保持模块导入和服务端渲染安全;不要把副作用搬进渲染函数或 `useMemo` 来规避 Effect。