- HOC
- RenderProps
- Hooks
一个可视化界面
- Container
- 负责发送数据
- Panel
- 展示title
- 通用功能
- 同环比功能,环比同比的触发功能
- debug功能,展示请求的json数据
- 进行功能扩展
- 在Header右侧支持功能的拓展
- Line
- 可视化展示界面
组件思想 逻辑UI分离
React 组件复用和组合 (一) | CaelumTian的博客 这里有讲到smart组件和dumb组件思想
SMART组件,负责应用逻辑,数据打交道。
DUMB组件,木偶组件,渲染结果只依赖于props,不应该依赖处React组件和其他DUMB组件
可复用逻辑有哪些
- 交互逻辑
- 业务逻辑
- 区块逻辑
有哪些组件?
React逻辑复用的特征
逻辑复用需要什么? 数据和action(可理解为变更数据)。即数据决定页面渲染,action是响应界面操作变更。
以一个弹窗逻辑为例
- 数据,即弹窗当前开关的状态。
- action,即改变弹窗逻辑的toggle函数。
HOC
设计思想
hoc1(hoc2(component))
通过包裹,React的单向流动的设计,并通过props把数据和action传递到子组件。
如
有哪些实践的HOC
- Redux的connect
- Antd表单
实践,通过connect传入相应的特定配置
如何交互的
- 通过props传入数据和action
问题
先明确概念
终组件 = hoc1(hoc2(原组件)))
- 不确定性(隐式依赖) & 命名冲突 & 代码难理解
原组件最终使用的props不确定是来自哪个HOC(高阶组件)带来的。
Hoc和原组件都使用从终组件传入的props,可能会导致命名冲突。
代码难理解,在终组件传入属性被哪个hoc消费,哪个hoc有什么监控逻辑,包裹了哪些hoc都不知道。
解法,要尽量减少hoc需要传入的属性,在connect就进行过属性名定制。
- 静态方法 & Ref 没法复制
因为层层包裹,Ref访问到原有组件,也无法放到到原有组价的静态方法
解法。
上面图表的实践
const DruidContainerHoc =
const PanelHoc =
const LineChart =
const ContainerPanelLine = DruidContainerHoc( PanelHoc (LineChart) ));
// 所有的相关运行态配置都在一起了
<ContainerPanelLine
...lineChartConfig
...PanelConfig
...ContainerConfig
</>
RenderProps
思想
function as child
一些用例
https://github.com/jaredpalmer/awesome-react-render-props
分类
上面案例实现
class Component{
render(){
return (<DruidContainer api={} params={}>
{(data, loading, requestJSON)=>{
return <Panel title="" loading={loading} requestJSON={requestJSON}>
<LineChart
xAisx
yAisx
data={data}
// 可能还有一些操作
/>
<Panel/>
}}
</DruidContainer>
})
}
Hooks
function render(){
const {data, loading, requestJSON} = useDruid(props);
return <Panel >
<LineChart/>
</Panel>
}
function DruidContainer(props){
useEffect()
}
总结
HOC | renderProps | Hooks | |
---|---|---|---|
拦截 | function as child | 钩子沟住动态 | |
大概图 | target = hoc1(hoc2(原组件)) 在使用时只看到这个target组件 |
{props=>{ return {props2=>{ return <元组件 …props …props2> } }} |
<>
<原组件>
各个组件是展开的 | function(){
const {} = useFunc1()
const
}
各个依赖也是展开的 |
| 优缺点 | 优点
- 可以不修改组件基础上,对组件极大改造。拦截和增强。
缺点
- 隐式依赖,不知道属性来自哪个hoc
- 属性会引起冲突
- 外界获取原组件困难
| 优点
- 显性依赖,
缺点
- 如果使用多,嵌套的地狱
- 只能在render时才能暴露出来,调用局限
| 优点
- 避免了组件的嵌套
- 更是UI和数据逻辑的分离
|
| 案例 |
- 做拦截,如权限、跳转、埋点、异常、描述、注入
- 层级少时做依赖注入非常方便,如redux的connect
| | |
| | | | |
借鉴
- 为什么 React 推崇 HOC 和组合的方式,而不是继承的方式来扩展组件? - 知乎
- 精读《React Hooks》 - 前端精读专栏 - SegmentFault 思否
- 论如何复用一个组件的逻辑 - 掘金 结合了Vue和React中mixin,hooks,hoc,优势和劣势
- React Hooks 之于 HoC 与 Render Props - 知乎
- React 组件复用和组合 (二) | CaelumTian的博客 RenderProps模式的深度讨论,数据流动,开放性,renderProps工具库,以及存在的问题
- React 组件复用和组合 (一) | CaelumTian的博客 HOC的深入,以及存在的问题
- weekly/75.精读《Epitath 源码 - renderProps 新用法》.md at master · dt-fe/weekly · GitHub 精读renderProps
- 译 使用 Render props 吧! - 掘金 介绍
- 可维护的 React 程序之复用与封装 - 知乎 讲renderProps
- 精读《我不再使用高阶组件》 - 知乎
renderProps的一些库