前端整洁架构 React+TypeScript 实现
参考资料
前言
个人能力有限,如有错误望指正。
我这个实现架构还是有不少的问题:
-
未使用依赖注入
-
各个模块依赖抽象
-
职责划分问题
-
最严的测试(😓实在是太忙)
当你在阅读这篇文章时,我假设你已经看完了 phodal Clean Frontend Architecture:整洁前端架构
且了解 bob 大叔设计的整洁架构
domain
我们先来看下目录结构,目录结构参考clean-frontend
├─src
├─code
├─domain
├─features
├─pages
├─presentation
├─router
└─stores
phodal 文章有讲到,这里我在做赘述。
router
: 路由
stores
: 状态管理
那么我们再来看下 domain
├─domain
├─admin
│ ├─adapter // 适配器
│ ├─model // 模型
│ ├─repositories // 容器
│ │ └─mapper // 字段映射
│ └─usecase // 用例
基本上一致,只是多了一个 adapter(适配器)。因为在 phodal 设计的架构中,我一直很好奇为什么没有 adapter(适配器)。
我认为是 angular
的 service
承担了adapter
的职责。
model
entity
实体是我们请求时接口返回给我们的类型。
model
这个model
则是我们UI
要使用的数据类型,类型与entity
会有细微出入。
repositories
我更喜欢叫 接口仓库,职责就是负责请求api
接口
mapper
负责将接口请求到的entity
转换成 UI
所需要的 model
数据。
adapter
我们再来看一句话:
这一层的软件结构的目的就是进行数据的转换,将便于用户实例和实体层操作的数据结构变化成为最便于外部结构(比如数据库或者 Web)操作的数据结构。比如 GUI 的 MVC 结构,表现器、视图器、控制器都是属于这个结构的。这层很可能是通过控制器将数据结构传给用户实例层,并且返回数据给表现器,视图器。
简单来说就是 可以通过adapter
将数据传递给 UI 层。
tips: repositories
下的 mapper 也是 adapter
。
所以我们可以将 react
的hook
封装成adapter
。
其他的我们就可以直接套用 phodal 设计的规则来编写业务代码。
usecase
负责 repositories
调用 and mapper
映射。
各层依赖关系
presentation <- adapter <- usecase <- repositories <- model
adapter
在我这个架构设计中,adapter
只是个普普通通的 hook
。
adapter 与 react context 结合
当我用context
的时候,习惯一股脑地所有方法全部扔 context
中。
这样会使context
职责过多,可以试着context
只放 state
, 一些业务函数呢可以放到adapter
, provider
则只需要暴露出状态和set
方法。
export const UserProvider = ({ children }) => {
const [user, setUser] = useState<UserModel>()
const [activeId, setActiveId] = useState<string>()
const [userAction, setUserAction] = useState<UserActionDetail>({} as UserActionDetail)
const value = useMemo(
() => ({
user,
activeId,
userAction,
updateUser: setUser,
updateUserAction: setUserAction,
updateActiveId: setActiveId
}),
[user, userAction, activeId, setUser, setUserAction, setActiveId]
)
return <UserContext.Provider value={value}>{children}</UserContext.Provider>
}
export const useGetUserActionListAdapter = () => {
const { activeId, updateUserAction, updateActiveId } = useUserContext()
const handleSomeThinkg = userAction => {
updateUserAction(userAction)
updateActiveId(0)
}
}
在对应的 adapter
使用该方法,最终在页面中使用我们自定义的hook
。
结尾
架构只是毛坯房,房子装修的好看不好看,决定这一切的还是"设计团队"、"装修团队"等。不要一上来就是整洁架构,因为整洁架构不是银弹!
转载自:https://juejin.cn/post/7080890082042839048