1. 认识高阶函数
-
什么是高阶组件呢?
认识高阶函数.png - 高阶函数: 接收一个或多个函数作为输入, 输出一个函数.
- 高阶组件: Higher-Order Components, 简称HOC
- 官方定义: 高阶组件是参数为组件, 返回值为新组件的函数.
2. 高阶组件的定义
- 高阶组件的调用过程类似于这样:
const EnhancedComponent = higherOrderComponent(WrappedComponent);
- 定义一个高阶组件
function enhanceComponent(WrappedComponent) {
return class NewComponent extends PureComponent {
render() {
return <WrappedComponent/>
}
}
}
const EnhanceComponent = enhanceComponent(App);
export default EnhanceComponent;
这里的名字随便起.png
嵌套关系改变.png
-
类表达式, 可以省略NewComponent
显示的名字.png - 所有的组件都可以起一个展示名称, 开发中很少重新定义名称
NewComponent.displayName = "Why";
- 给经过处理的高阶组件传递属性
- 高阶组件并不是React API的一部分, 他是基于React的组合特性而形成的设计模式;
- displayName是给组件改名字
- 做了一个劫持, 可以做很多操作.
- 高阶组件在hooks出现后用的比较少
- redus、路由, 很多东西用的都是高阶组件
3. 高阶组件的应用
1. 增强props
增强.png-
context共享数据
context共享.png
2. 渲染判断鉴权
- 在开发中, 我们可能遇到这样的场景:
- 某些页面是必须用户登录成功才能进行进入;
-
如果用户没有登录成功, 那么直接跳转到登录页面;
鉴权.png
-
3. 对生命周期进行劫持
生命周期劫持.png- 打印渲染的耗时
- 不安全的生命周期函数, UNSAFE_componentWillMount
- 早期的时候支持mixin: 混入
- hooks一定是未来, 真的好用
- 高阶组件增强代码的复用性, 写出优雅的代码
- 反向继承,
-
一边学习一边看官方文档, 学习方法, 官方文档中的专业词汇, 也会涉及到其他的概念
不要创建自己的组件基类.png
4. 高阶函数的意义
- 我们会发现利用高阶组件可以针对某些React代码进行更加优雅的处理.
- 其实早期的React有提供组件之间的一种复用方式是mixin, 目前已经不再建议使用:
- Mixin可能会相互依赖, 相互耦合, 不利于代码维护
- 不同的Mixin中的方法可能会相互冲突
- Mixin非常多时, 组件是可以感知到的, 甚至还要为其做相关处理, 这样会给代码造成滚雪球式的复杂性
- 当然, HOC也有自己的一些缺陷:
- HOC需要在原组件上进行包裹或者嵌套, 如果大量使用HOC, 将会产生非常多的嵌套, 折让调试变得非常困难;
- HOC可以劫持props, 在不遵守约定的情况下也可能造成冲突;
- Hooks(React v16.8开始)的出现, 是开创性的, 它解决了很多React之前存在的问题
- 比如this指向问题、比如hoc的嵌套复杂度问题等等
5. ref的转发
- 在前面我们学习ref时讲过, ref不能应用于函数式组件
-
forwardRef, 高阶组件是一个函数
ref的转发.png
6. Portals的使用
-
某些情况下, 我们希望渲染的内容独立于父组件, 甚至是独立于当前挂载到的DOM元素中(默认都是挂载到id为root的DOM元素上的).
优秀的方案.png
7. Modal组件案例
- 比如说, 我们准备开发一个Modal组件, 它可以将它的子组件渲染到屏幕的中间位置
步骤一:修改index.html添加新的节点
<div id="root"></div>
<!-- 新节点 -->
<div id="modal"></div>
步骤二:编写这个节点的样式:
#modal {
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
background-color: red;
}
步骤三:编写组件代码
import React, { PureComponent } from 'react';
import ReactDOM from 'react-dom';
class Modal extends PureComponent {
constructor(props) {
super(props);
}
render() {
return ReactDOM.createPortal(
this.props.children,
document.getElementById("modal")
)
}
}
export default class App extends PureComponent {
render() {
return (
<div>
<Modal>
<h2>我是标题</h2>
</Modal>
</div>
)
}
}
网友评论