用于设计、审查、生成或重构使用Effector、effector-react、Farfetched、AtomicRouter、@effector/next等库的React应用。
Effector 生态系统技能
功能概述
Effector 生态系统技能是一项面向实际任务的技能,主要用于使用此技能来应用使用或计划使用的前端应用程序 : React 或 React- concompatible UI. 效果器用于商业逻辑和状态;Effector- react for binding un。
核心要点
- 它将相关步骤、工具调用和结果整理方式集中到统一流程中,帮助使用者更快完成目标并减少重复操作。
- 使用时应结合输入条件选择合适的执行方式,核对必要参数、依赖环境与输出内容,并按原始要求处理异常情况。
- 从功能定位来看,该技能强调把分散的操作要求整理成清晰、可复用的处理流程,使用户能够围绕既定目标快速准备输入、选择执行方式并获得结构化结果。
使用与执行
实际使用前应先确认任务范围、数据来源、运行环境、必要权限和关键参数,再依据技能说明逐步执行;若输入条件不完整,应先补齐信息或采用保守配置,避免因错误假设导致结果偏离需求。执行过程中需要关注工具调用是否成功、接口或依赖是否可用、输出格式是否符合预期,并对异常提示、缺失字段和边界情况进行处理;
结果检查与注意事项
涉及批量任务时,还应保存进度,避免中断后重复操作。该技能适合用于一次性任务,也可以接入自动化工作流,与其他技能或上层代理配合完成更完整的业务链路;在组合使用时,应明确每一步的输入输出关系,并避免不同步骤之间出现参数冲突。
Effector 生态系统技能
用途
在以下前端应用中使用该技能(当前已采用或计划采用):
- React 或与 React 兼容的 UI 框架
- Effector 管理业务逻辑与状态
effector-react将 Effector 单元绑定至组件- Farfetched 处理远程操作
@withease/contracts或兼容的 contracts 实现运行时校验- Effector 生态支持包:
patronum、atomic-router、effector-storage、effector-action、effector-forms、@withease/factories、@withease/i18next、@withease/web-api、@effector/next、@effector/reflect、@withease/redux、eslint-plugin-effector、Effector Babel/SWC 插件
该技能不规定项目结构。示例中可能使用 entities/user 或 shared/api 等路径,但不得决定 Feature-Sliced Design(FSD)的分层与切片规则。当问题主要涉及层级划分、切片边界、公共 API 设计、导入限制、文件组织方式或 Effector 项目的整体结构时,请改用 effector-fsd 技能。
目标架构原则如下:
UI 是被动的;业务逻辑是声明式的;远程数据需经运行时校验;启动流程显式且作用域明确;远程操作语义应被建模,而非隐藏在 React 组件中。
触发条件
当用户提出以下类型的问题时启用该技能:
- Effector 模型设计
sample、combine、attach、effects、stores、events、factories、Scope、SSR、scopeBind- 使用
useUnit进行 React 绑定 - Farfetched 的 query/mutation/barrier/cache/并发控制/contracts
- Atomic Router 的路由模型与路由加载器(route loaders)
@effector/next、App Router、Pages Router、SSR、hydration、Scope 序列化- 持久化、表单、国际化(i18n)、浏览器 API、测试及生态包选型
- 审查代码中是否存在 Effector/Farfetched/Scope/React 反模式
- 为模型、查询、变更、表单、路由、持久化或测试生成模板
切勿将本技能作为 FSD 结构的首要依据。有关模块放置与导入边界的决策,请使用 effector-fsd。
首次响应行为
作答前,首先识别用户目标:
- 设计新模型或数据流
- 重构已有模型/组件/API 操作
- 审查某段代码片段
- 选择生态包
- 创建 query、mutation、route、form、persistence adapter 或 test
- 集成 SSR/Next.js/Scope
若用户提供代码,请基于本技能规范进行审查,并返回以下内容:
- 做得好的地方
- 存在的问题
- 问题成因
- 最小可运行的修正版本
- 仅在必要时提供放置建议(示例性质),除非
effector-fsd同时在上下文中被启用
完整审计模式
当用户要求“完整审计”、“深度审查”、“架构审计”或“是否全部符合最佳实践?”时,不应止步于局部反模式,而应执行跨切面的静态数据流审计。在撰写最终回答前,请构建并检查以下六类图谱:
- 启动图谱(Startup graph):
main/入口 →fork/Provider→appStarted→ 存储/会话恢复 → 路由器/历史记录初始化 → 初始路由打开。标记任何在认证状态未知前即打开受保护路由的路由器/历史记录启动逻辑。 - 认证生命周期图谱(Auth lifecycle graph): 登录成功、会话恢复成功/失败、登出/清除会话、Token 刷新、
401/403API 错误、路由重定向、受保护路由拒绝访问。标记所有未同步更新路由状态的sessionCleared/登出/未授权路径。 - 远程操作图谱(Remote-operation graph): 每个 Farfetched query/mutation、其触发源、刷新/失效来源、
concurrency配置、abortAll行为、缓存/更新策略、以及$pending门控逻辑。标记重复触发、非预期的TAKE_EVERY、陈旧结果竞争(stale-result races)、页面模型在其对应路由已关闭时仍尝试重新获取数据等行为。 - Scope 与外部回调图谱(Scope and external callbacks graph): 定时器、历史监听器、DOM/浏览器事件监听器、SDK 回调、WebSocket、存储拾取(storage pickup)、HMR/卸载清理逻辑。标记模块级可变句柄(如
let intervalId)、缺失的scopeBind、以及已声明但从未被调用的appDestroyed/stop 事件。 - 响应式纯度图谱(Reactive purity graph): 所有
sample.fn、combine、store 的.map、reducer 和 contracts。标记可能抛出异常的转换(如new Date(...).toISOString()、JSON.parse、不安全属性访问)、过长的内联算法、以及错误地从操作$data读取而非从clockpayload 中读取的成功处理器。 - React 异步边界图谱(React async boundary graph): 向 callback props 传递 Effector 事件并期望返回
Promise的组件、围绕 Effector 事件维护本地 pending 状态的组件、直接发起路由/API 调用的组件、或在 JSX 中执行业务分支逻辑的组件。
对每一项发现,需包含:文件/路径证据、严重等级、影响说明、最小修复方案、验收标准。若问题并非直接可见,而是基于 Effector 静态图语义推导得出,请明确标注为“推断风险”,并展示构成该风险的单元链路。
不可协商的核心原则
1. UI 必须保持被动
React 组件必须做到:
- 仅渲染数据
- 调用已在模型中预先定义好的事件、effects、query/mutation 触发器或路由动作
- 向更底层的无状态组件透传 props
- 通过
useUnit绑定 Effector 单元
React 组件禁止:
- 嵌入业务决策逻辑
- 直接调用 API
- 基于领域工作流规则做条件分支
- 在 render 阶段调用
sample、createEvent、createStore、createEffect或 factories - 通过
$store.getState()读取 store 值 - 使用
watch实现应用行为逻辑 - 在可能使用 Scope/SSR 的场景下,将原始事件/effect 直接传递给 DOM 处理器或普通 callback props
2. 推荐每个连接组件只使用一种 useUnit 形状
对于从同一模型中读取/调用多个 Effector 单元的组件,推荐使用单次 useUnit 调用,并以对象或数组形式传入:
const { value, submitDisabled, onValueChange, onSubmit } = useUnit($$form);
或:
const [value, submitDisabled, onValueChange, onSubmit] = useUnit([ $value, $submitDisabled, valueChanged, submitted, ]);
随后解构所有返回值,并将绑定后的回调函数传入 JSX。对于 handler 类型的值,应在 useUnit 返回时使用 React 风格的 on* 别名:暴露 onSubmit: submitted、onValueChange: valueChanged、onRetryClick: retryClicked。Effector 事件本身应在模型中按事实命名;别名仅用于 React 绑定目的。
避免在同一组件中重复调用 useUnit:
// 默认视为不良实践:冗余且在重构时易不同步 const value = useUnit($value); const submitDisabled = useUnit($submitDisabled); const onValueChange = useUnit(valueChangedEvent);
当订阅粒度成为关键考量时,应拆分组件,而非在一个组件中散布多个 useUnit 调用。
3. Effector 模型必须静态且声明式
仅在模块顶层创建单元。
应使用:
createEvent表达已发生的事实createStore表达状态createEffect仅用于 Farfetched 尚未覆盖的副作用attach声明式地向 effect 注入 stores/参数sample作为主要连接操作符combine构造视图模型(view models)split或effector-action在提升可读性时处理复杂分支- 具名纯函数处理
combine、sample.fn或 store.map中的非平凡数据转换 patronum提供常见操作符:防抖、节流、重置、状态、pending 辅助工具等- factories 实现具有相同结构、需独立实例的重复模型逻辑
scopeBind用于离开 Effector 调用栈但仍需在 Scope 内正常工作的回调
应避免:
- 在 effects 中编写命令式链式逻辑
- 在 effects 中嵌套调用事件
- 使用
watch实现业务逻辑 - 在生产逻辑中使用
$store.getState() - 从 React 组件中动态创建模型
- 将派生 store 用作变更目标
- 在
combine、sample.fn或 store.map中内联编写过长的映射、排序、分组、归一化或格式化逻辑 - 在 store reducer 中返回
undefined,除非明确设置了skipVoid: false - 臃肿的模型同时承担多个互不相关的业务流程
- 使用巨型对象 store,而若干原子 store 更清晰
优先按关注点划分子模型,而非构建大而全的单一模型。当模型逐渐承载多个业务流程时,应将其拆分为子模型,例如 $$form、$$filters、$$list、$$selection 或 $$dialog;每个子模型应仅负责自身状态与本地规则。顶层模型应保持轻量,仅通过 sample 及其他声明式连接协调子模型之间的交互。
通过将非平凡的数据转换提取为具名纯函数,维持 Effector 模型的声明式特性。简单的布尔判断或字段拼接可保留在内联位置;复杂的映射、排序、分组、DTO 归一化、权限驱动的视图模型、格式化逻辑等,应置于所属模型/API/领域辅助模块附近。模型的作用应是连接 stores/events 并调用这些函数,而非将算法逻辑隐藏在响应式操作符内部。
对于重复出现的表单、筛选器、小部件或其他具备相同行为的独立实例,应优先选用 factories,而非复制粘贴 Effector 模型代码。在 SSR/Scope/SID 敏感型应用中,使用 @withease/factories 并配置 Effector Babel/SWC 插件的 factories 字段;factory 调用必须位于模块顶层,严禁在 render 阶段调用。
4. Farfetched 全权管理远程操作
使用 Farfetched 处理后端通信:
createJsonQuery处理数据读取createJsonMutation处理数据写入declareParams提供类型化的参数定义() response.contract实现运行时校验mapData在校验后映射 DTOmapError: ({ error }) => ...使用当前 Farfetched 对象参数格式规范化传输层/校验层/领域层错误concurrency操作符用于路由/搜索/筛选取消;提交去重应优先使用显式的 Effector$pending门控,谨慎选择 Farfetched concurrencycreateBarrier+applyBarrier处理 Token 刷新或资源不可用流程keepFresh、cache、.refresh和update在适当时机表达刷新/缓存语义request.fetch.credentials在当前 Farfetched 代码中用于 Cookie/Session API@farfetched/atomic-router在使用 Atomic Router 时实现查询驱动的路由加载
绝不可在无运行时 contract 的前提下信任后端数据。
5. 应用启动必须显式且作用域明确
优先使用一个应用级事件(如 appStarted)和一个页面/路由级事件(如 pageStarted),而非多个松散的启动函数。
默认模式:
const scope = fork();
await allSettled(appStarted, { scope, params: startParams });
从该事件出发,通过 sample 或 effects 连接存储拾取、i18n 初始化、路由器启动、初始查询及浏览器集成逻辑。默认情况下应避免如下序列:
await startAppClock(scope);
await allSettled(appStarted, { scope });
await startRouter(scope);
该序列默认视为错误。应将适配器安装建模为由 appStarted 启动的 effects(例如 sample({ clock: appStarted, target: routerStartedFx }))。仅在极少数无法用 scoped effect 表达、且必须在首个回调触发前完成的宿主集成边界场景下,才可保留自由浮动的 startAppClock(scope) / startRouter(scope),并需明确文档化。所有业务决策仍必须由 appStarted、路由事件或 scope-bound 回调触发。
仅在你明确需要等待那些在 allSettled(event, { scope }) 调用之外(例如由定时器、SDK、历史监听器或 WebSocket 的 scopeBind 回调)触发的异步任务时,才使用 allSettled(scope)。
6. 包的选择应基于具体目的
不要因流行而引入包,仅在它能解决特定架构问题时才选用。
请参考 references/01-package-map.md 中的包映射关系,以及 references/10-ecosystem-library-notes.md 中的详细说明。
路径示例
代码示例中可能使用如下路径别名:
@/shared/api/base-url @/entities/session @/features/profile-update @/pages/user/model/page.model
这些仅为示意,不可从中推断完整的项目结构规则。有关模块放置与边界决策,请使用 effector-fsd。
命名规范
Stores:
export const $user = createStore(null); export const $isAuthorized = createStore(false);
Events:
export const formSubmitted = createEvent(); export const searchChanged = createEvent (); export const pageOpened = createEvent();
useUnit UI 绑定形状应将这些事件暴露为 handler 别名:
export const $$form = {
value: $value,
onValueChange: valueChanged,
onSubmit: formSubmitted,
};
Effects:
export const analyticsTrackedFx = createEffect();
Queries/mutations:
export const userQuery = createJsonQuery(...); export const updateProfileMutation = createJsonMutation(...);
避免模糊命名:
// 不良实践 export const setData = createEvent(); export const update = createEvent(); export const fx = createEffect();
必需参考文档
在给出详细回答前,请查阅以下相关文件:
references/00-source-policy.mdreferences/01-package-map.mdreferences/03-effector-modeling.mdreferences/04-farfetched-contracts.mdreferences/05-react-ui-binding.mdreferences/06-routing-forms-persistence-i18n.mdreferences/07-testing-tooling.mdreferences/08-anti-patterns.mdreferences/09-review-checklist.mdreferences/10-ecosystem-library-notes.mdreferences/11-nextjs.mdreferences/12-production-audit-playbook.md
默认回答风格
力求具体,优先提供可运行的代码示例。
修正代码时,先展示最小正确版本,再解释原因。
当模块放置是核心问题时,应主动切换至或请求启用 effector-fsd。
当某项选择存在权衡时,应说明默认推荐方案及偏离条件。
热门AI工具
相关专题
本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。
0
2026.10.22
本专题介绍Gradle Wrapper的基本作用,涵盖文件组成、生成方法、版本配置和任务调用,帮助你理解项目如何使用指定的Gradle版本,减少不同开发环境带来的构建差异。
0
2026.10.22
本专题整理Golangci-lint常用Linters的用途与配置方法,覆盖错误处理、无效代码、安全、复杂度、命名和依赖检查,帮助项目合理选规则。
0
2026.10.22
本专题介绍Gradle Java项目构建方法,涵盖Java插件配置、依赖声明、源码编译、测试执行和打包检查,帮助你理解各阶段的任务关系,逐步完成项目构建。
0
2026.10.22
本专题汇总PHP常见时间戳漏洞,包括2038年溢出、时区漂移、时间戳伪造、重放攻击、时间盲注与日志审计失效等,并给出升级64位环境、使用 DateTimeImmutable、统一UTC、严格超时校验、预处理绑定、hash_equals 比对等修复方案,帮助开发者快速排查和加固时间相关代码。
0
2026.10.22
本专题聚焦Golangci-lint YAML配置文件,讲清运行参数、规则启停、目录排除、问题过滤及严重级别设置,便于团队统一检查标准。
0
2026.10.22
本专题讲解Golangci-lint的安装、初始化、基础命令和首次代码检查,覆盖本地环境、Docker及多平台用法,帮助Go开发者快速上手。
0
2026.10.22
PHP2Shell漏洞是什么,哪些PHP版本和运行环境会受到影响,服务器应该如何检测与修复?本专题提供版本自查脚本、Linux与Docker升级命令、PHP-FPM和Apache排查步骤,以及修复验证、临时缓解和应急响应方案。
0
2026.10.22
热门下载
相关下载
精品课程
共86课时 | 27.8万人学习
共18课时 | 6.1万人学习
共31课时 | 5万人学习
最新文章
