导语:复杂业务逻辑复用一直是React
组件开发中的一大难题,团队目前同质化业务比较多,我们的想法是直接复用已有的逻辑代码,因为还要考虑到数据的拉取,展示,显然纯UI组件不能满足我们的需求。前段时间也在复杂业务组件抽取上下了不少功夫。本文将使用近期非常火的React Hook
特性抽取常用的业务组件,并比对业界已有方式,借此尝试探索出一套优雅的组件复用方案。
背景
现有的业务采用Redux
管理业务数据,各模块关注的Reducer
、Action
是分散的,并且所有数据使用唯一Store
储存。如果直接通过拷代码的方式,需要同时关注Reducer
、Action
目录,然后修改顶层Store
中关注的Reducer
。这样的开发方式对二次开发者来说非常不友好,理清原有代码然后复用的时间消耗不亚于自己重写一套逻辑。为了减少不必要的开发耗时,封装常用的复杂业务模块迫在眉睫。
现阶段方式
首先我们将开发方式由纵向开发转为横向开发。即将同一业务模块的Reducer
、Action
、index
放置同一文件夹。
目录结构如下:
component
|———reducer
|———action
|———accets
|___index.js
|___index.less
这样还是和原始React
+Redux
的开发方式一样,而二次开发者只需要拷贝业务模块文件夹再做细节修改了。
其实这样的开发方式仅仅是减少了开发者在多个文件夹来回切换的耗时,他们还是需要梳理模块内部逻辑,并且需要在顶层Store
中添加数据关注。除非我们使用更多的Props
使得组件可以满足各种场景,开发者只需要传递相关属性,即可直接使用,这样就会使得我们的业务组件非常的重,有相当多作为判断用的鸡肋般的代码。
React Hooks
不了解React Hooks
的同学可以先移步React Hooks的简单介绍
Hooks
的实质是把面向生命周期编程变成了面向业务逻辑编程。此时我们业务组件的封装方式可以修改成Hooks
+ UI Component
。下面使用「排行榜」复杂业务模块的封装来进行实例说明。
1、Hooks逻辑
import React, { useEffect, useState } from 'react'
import _ from 'axios'
function useRank (cgi, params) {
const [rankList, setRankList] = useState([])
const [myRank, setMyRank] = useState({})
const [isEnd, setIsEnd] = useState(0)
// 第二个参数传递 [] 相当于将effect作为class Component中的componentDidMount使用
useEffect(() => {
let query = ''
Object.keys(params).forEach((key, idx) => {
query += idx === 0 ? `?${key}=${params[key]}` : `&${key}=${params[key]}`
})
// 拉取逻辑
_.get(`${cgi}${query}`)
.then(res => {
const { myRank, rankList, isEnd } = camelcase(res.data.result)
setRank(rankList)
setMyRank(myRank)
setIsEnd(isEnd)
})
.catch(e => console.log(e))
}, [])
return {
myRank, rankList, isEnd
}
}
2、UI Component
import React from 'react'
import { useRank } from './hooks'
const Rank = ({
cgi = ''
params = { off_set: 0, page_size: 10 },
}) => {
// 使用自定义Hook
const { rank = [], myRank, isEnd } = useRank(cgi, params)
return (
<div>
...
</div>
)
}
export default Rank
按这种方式我们可以在需要拉取rank数据的时候直接调用方法获取到,并且不同组件中数据相互独立,非常适用于多榜单切换的情况,如下图
const { rank = [], myRank, isEnd } = useRank(cgi, params)
业界其他方式
具体参考React Hooks深入不浅出
感谢阅读,祝大家新年快乐~~~~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。