当前位置: 首页 > news >正文

前端抽象化,打破框架枷锁:react现代化项目中的思想体现

引言
这一系列前文分别拆解了多端通讯、HTTP 请求、路由等专题,以及 OOP 在现代前端中的用法。但回到真实项目,时间与经验往往不允许我们一开始就搭一个“理想架构”甚至连设计一个高质量的模块都没时间,更多时候,我们需要在几小时内启动新项目,或在存量代码上渐进式重构、进行二开。
这篇文章给出一套“够用且可演进”的 React 现代化分层实践:把展示、状态/副作用、业务用例与服务边界划清,让组件更轻、逻辑更聚焦、测试更可控;同时尽量与框架解耦,方便未来迁移或替换实现。
文末附有可复制的 AI 提示词,可在 Cursor、VS Code 等 IDE 中约束生成严格遵循本文分层的代码。随着项目演进,建议同步更新提示词以贴合你的领域模型与团队规范。

基于 DDD 的前端分层实践(React + TypeScript)

这是一套面向react前端的轻量分层规范,目标是把“展示、状态、副作用、业务逻辑、数据访问”清晰拆开:组件更轻、用例更清晰、服务更可复用、测试更可控。它不追求“全能框架”,而是帮助你在日常迭代中,稳步提升可读性与可维护性。并且将业务逻辑与 React 解耦,方便未来迁移到其他框架(如 Vue、Svelte、原生 Web Components)。

架构图

在这里插入图片描述

🎯 各层职责与内容

1. Component(UI 层)

  • 职责: 纯展示与交互承载。
  • 包含: React 组件(例如 Modal、Form、Button)、样式与布局、交互事件绑定。
  • 设计原则:
    • css使用原子化css(如tailwindcss,unocsss),一次性解决大量关于css的老问题
    • 可以包含纯 UI 的本地 state(例如弹窗显隐、输入值、hover 状态),但与业务数据分离
    • 不包含业务规则与流程
    • 不直接操作全局/业务状态(通过 Hook/Store 获取数据与动作)
    • 高复用组件尽量保持“更小、更纯”,页面层多写一点没关系,避免把变化集中堆到一个“巨石组件”里

2. Hook/Store(状态管理层)

  • 职责: 管理可视状态与副作用,承载微型业务 Store,并协调全局 Store;对外暴露“响应式数据 + 动作”。
  • 包含:
    • 非 Store 型 Hook:useStateuseReduceruseEffectuseCallback
    • 微型业务 Store:按功能模块拆分的模块级单例 Store(仅存状态与同步修改,不写业务流程)
    • 协调全局 Store:整合用户信息、主题、语言等跨模块状态
    • 将多个 UseCase 进行场景化组合,为组件提供统一的数据接口
  • 设计原则:
    • UI 层只关心可视状态;业务数据通过 Hook/Store 提供
    • 协调本地状态、微型 Store 与全局 Store 的边界
    • 处理异步与副作用,把复杂度挡在组件之外
    • 对内调用 UseCase,对外仅暴露数据与交互函数

示例(登录:本地表单 state + 用例调用)

// hooks/useAuth.ts
import { useState } from 'react'// 假 UseCase(真实项目替换为注入的 UseCase 实例)
type Credentials = { username: string; password: string }
type User = { id: string; name: string; token: string }const loginUseCase = async (cred: Credentials): Promise<User> => {if (!cred.username || !cred.password) throw new Error('EMPTY')return { id: 'u1', name: cred.username, token: 'token-xxx' }
}
const logoutUseCase = async (): Promise<void> => Promise.resolve()export function useAuth() {// 业务相关状态(Hook 管理并暴露)const [username, setUsername] = useState('')const [password, setPassword] = useState('')const [user, setUser] = useState<User | null>(null)const [loading, setLoading] = useState(false)const [error, setError] = useState<string | undefined>()const login = async () => {setLoading(true); setError(undefined)try {const u = await loginUseCase({ username, password })setUser(u)} catch (e) {setError('登录失败,请检查账号或稍后再试')} finally {setLoading(false)}}const logout = async () => {await logoutUseCase()setUser(null)setPassword('')}return {username, setUsername,password, setPassword,user, loading, error,login, logout,}
}

3. UseCase(业务逻辑层)

  • 职责: 承载“可读的业务流程”,进行领域规则校验与服务编排。用例是变化最频繁的地方,必须一眼读懂、注释清晰。
  • 示例:
    // 示例:展示流程可读性与依赖注入
    class DemoUseCase {constructor(private readonly aService: AService,private readonly bService: BService,private readonly cStore: Store) {}async execute(href: string, storeData: Partial<StoreState>) {// 1) 获取 A 数据const aData = await this.aService.getA(href);// 2) 基于 A 数据获取 Bconst b = await this.bService.getB(aData);// 3) 更新 Store(也可选择返回结果,由 Hook/Store 处理)this.cStore.update({...storeData,b,});// 推荐返回领域实体/DTO,而非裸数据return b;}
    }
    
  • 包含: 业务用例类(如 ImageStoryUseCase、ScriptGenerationUseCase)、完整的业务流程方法、业务规则验证、构建/协调领域实体。
  • 设计原则:
    • 用例包含完整的业务流程与校验
    • 协调多个 Service 调用,屏蔽技术细节
    • 返回领域实体或 DTO,而非原始数据
    • 方法“无实例依赖状态”,不把业务长期状态挂在类字段上
    • 与 React 解耦,保持纯 TypeScript

4. Service(外部服务层)

  • 职责: 集成外部系统与技术细节,提供可复用的“纯函数式”能力。
  • 包含: 技术实现(图片处理、网络请求、加解密、格式转换等)、错误包装与重试策略、可被多个 UseCase 复用的函数/模块。
  • 设计原则:
    • 尽量写成纯函数:输入 → 输出,不依赖外部闭包/全局状态
    • 所需依赖通过显式参数传入(而非偷偷引用)
    • 聚焦技术细节,屏蔽上层业务语义
    • 与 React 解耦,保持纯 TypeScript

📊 状态管理策略

  • 功能模块状态: 按“模块”拆分多个微型 Store(而非按页面),优先单例
  • 纯 UI 状态: 组件内 useState,与业务解耦,只服务于视觉/交互
  • 业务流程状态: 放在 UseCase 的执行流程里,以局部变量或参数传递,避免在类上维护长期状态
  • 全局状态: 全局 Store(如用户信息、主题、语言等),仅在确有共享需求时引入

数据流向

用户操作 → Component(触发动作) → Hook/Store(协调 Store 与 UseCase) → UseCase(执行业务) → Service(外部交互/数据访问) → Store(更新) → Component(渲染)

设计模式应用

  • 依赖注入(DI): UseCase 通过构造函数注入 Service,降低耦合
  • 策略模式: 把“可替换的规则/算法”抽象为策略,方便扩展
  • 观察者/事件总线: 跨页面、跨组件通信(如 ChatBox)用事件流解耦

🧪 测试策略

  • Component 层: 不建议做单测,保障可访问性与视觉回归即可
  • Hook/Store 层: 不建议做重单测,尽量把复杂逻辑下沉到 UseCase
  • UseCase 层: 强烈建议做单测,这是性价比最高的测试点
  • Service 层: 被 UseCase 覆盖;必要时做集成/契约测试(API 客户端/SDK 按团队规范)
  • 注: 谦卑对象模式(Humble Object Pattern)把难测试的 UI/外部交互与“可测试的核心逻辑”拆开,核心逻辑独立为纯对象做单测。

错误处理机制

  • 错误分类:
    • 领域错误: 业务规则校验失败(如 StoryValidationError)
    • 基础设施错误: 外部服务/网络失败(如 ImageUploadError)
    • 应用错误: 用例编排/应用层错误(如 UseCaseError)
  • 处理流程:
    1. Service 捕获原始错误 → 包装为可识别的应用/基础设施错误
    2. UseCase 根据业务语义抛出领域错误
    3. Hook 统一兜底,将错误转成用户可读的提示与可恢复动作
    4. Component 仅负责展示(不做错误分流与恢复逻辑)

性能优化策略

  • 状态优化: useMemo 做派生数据,useCallback 控制引用稳定性;适度使用 React.memo,以真实瓶颈为依据
  • 业务优化:
    • UseCase 方法尽量“无实例状态”,只依赖入参与返回值
    • 多微型 Store,少巨大组件的本地 state,便于子组件拆分与重用
    • Store 只负责“状态 + 简单的同步修改”,业务流程放入 UseCase
    • 统一 Tailwind 设计令牌(圆角、边框、主题、阴影),减少随意发挥

🤖 AI 生成提示词(可直接复制使用)

请严格按照“组件 Component → Hook/Store → UseCase → Service”的分层生成 React + TypeScript 代码,并遵守以下约束:

  1. 目标与范围
  • 输出满足下述“功能描述”的最小可用实现,并提供必要的类型与依赖注入示例。
  1. 分层要求(必须遵守)
  • Component: 仅展示与交互,不包含业务规则;可以使用纯 UI 的本地 state;不直接读写全局/业务状态;通过 Hook/Store 获取数据与动作。
  • Hook/Store: 管理可视状态与副作用;承载微型业务 Store(模块级单例,存状态与同步修改);协调全局 Store;对内组合调用 UseCase,将用例中逻辑得到的数据变为状态,对外暴露数据与动作。
  • UseCase: 编排完整业务流程,做领域校验;不依赖 React;方法不依赖实例长期状态;返回领域实体/DTO(必要时由 Hook/Store 更新状态)。
  • Service: 技术细节与外部交互的“纯函数”,所需依赖显式入参传入;不依赖 React;可复用。
  1. 错误与边界
  • 分类: 领域错误/基础设施错误/应用错误;在 Service 包装原始错误,在 UseCase 识别并抛出领域错误,在 Hook 转换为用户可读信息,哪怕和前面一样,也要有一个单独定义函数调用的过程。
  1. 代码风格与命名
  • UseCase 命名: XxxUseCase;Service 函数: getXxx/createXxx;错误以 XxxError 结尾。
  • 所有模块使用 TypeScript,避免 any(必要时用最小可行类型)。
  • 代码简洁、注释清晰,变量命名语义化,避免缩写与模糊词。
    请按上述规范完整输出,不要省略分层与类型。

求点赞,求关注,求收藏,求转发,欢迎各位也看看这个系列其他部分。


文章转载自:

http://ZWCMmDb0.tkbfL.cn
http://OeHzPhYV.tkbfL.cn
http://3tQIeyTy.tkbfL.cn
http://q0RD3OZ2.tkbfL.cn
http://iiNYKgga.tkbfL.cn
http://PsO5dKJp.tkbfL.cn
http://nyUwofNJ.tkbfL.cn
http://pcNOTJTY.tkbfL.cn
http://cg2HLORu.tkbfL.cn
http://btH7mlje.tkbfL.cn
http://0gGR9zPb.tkbfL.cn
http://rnVmlDt0.tkbfL.cn
http://QDvucibm.tkbfL.cn
http://ygZxFK8x.tkbfL.cn
http://Iq8d5WXI.tkbfL.cn
http://ZzbWug8G.tkbfL.cn
http://HuALVf1c.tkbfL.cn
http://QqMWiMQm.tkbfL.cn
http://TpwgkxR3.tkbfL.cn
http://cu6imD45.tkbfL.cn
http://WPDVQ9md.tkbfL.cn
http://xXfpNWuQ.tkbfL.cn
http://5OHphttc.tkbfL.cn
http://pWqsYYuA.tkbfL.cn
http://gTpupCjD.tkbfL.cn
http://5Uh6HDpg.tkbfL.cn
http://SjwUoMCn.tkbfL.cn
http://MIdm2Ncc.tkbfL.cn
http://izcmnQwt.tkbfL.cn
http://TGhA01zF.tkbfL.cn
http://www.dtcms.com/a/378582.html

相关文章:

  • 基于开源AI智能名片、链动2+1模式与S2B2C商城小程序的流量运营与个人IP构建研究
  • gstreamer:创建组件、管道和总线,实现简单的播放器(Makefile,代码测试通过)
  • Kibana 双栈网络(Dual-Stack)支持能力评估
  • go 日志的分装和使用 Zap + lumberjack
  • 河北智算中心绿色能源占比多少?
  • 在能源互联网时代天硕工业级SSD固态硬盘为何更受青睐?
  • 关于rust的crates.io
  • 使用Rust实现服务配置/注册中心
  • C++ 类与对象(下):从构造函数到编译器优化深度解析
  • DNS 域名解析
  • EasyDSS重装系统后启动失败?解决RTMP推流平台EasyDss服务启动失败的详细步骤
  • 自动驾驶中的传感器技术45——Radar(6)
  • 第四章 Elasticsearch索引管理与查询优化
  • 拆分了解HashMap的数据结构
  • Sqlite“无法加载 DLL“e_sqlite3”: 找不到指定的模块”解决方法
  • 项目 PPT 卡壳?模型效果 + 训练数据展示模块直接填 ,451ppt.vip预制PPT也香
  • react-native项目通过华为OBS预签名url实现前端直传
  • Linux-> UDP 编程1
  • Pytest+requests进行接口自动化测试2.0(yaml)
  • 【容器使用】如何使用 docker 和 tar 命令来操作容器镜像
  • 科普:在Windows个人电脑上使用Docker的极简指南
  • 【面试场景题】电商订单系统分库分表方案设计
  • 微服务保护全攻略:从雪崩到 Sentinel 实战
  • springcloud二-Sentinel
  • Redis 持久化与高可用实践(RDB / AOF / Sentinel / Cluster 全解析)
  • Semaphore 信号量深度解析
  • 门店网络重构:告别“打补丁”,用“云网融合”重塑数字竞争力!
  • Linux操作系统之Ubuntu
  • WSL自定义安装多个相同版本的Ubuntu子系统
  • 晶振在5G时代的角色:高精度时钟的核心支撑