react
中的高阶组件主要是对于 hooks
之前的类组件来说的,如果组件之中有复用的代码,需要重新创建一个父类,父类中存储公共代码,返回子类,同时把公用属性传到子类中的形式。当然对于现在的 hooks
来说基本用不到了。但是 HOC
的形式也是对应 react
而衍生出来的一种设计形式。我们仅需了解一下它的形式,你可能不会在工作中用到,但是当你维护老的项目时,也可能会接触到。本节只了解简单的使用(小编也没有深入使用过),不做深入探讨。
使用示例
高阶组件就是一个函数,传给它一个组件,它返回一个新的组件
代码语言:txt复制const NewComponent = higherOrderComponent(OldComponent)
示例
我们定义组件共用 show
和 hide
方法。自己的组件显示之前可以有 loading
状态显示加载中
const loading = message => OldComponent => {
return class extends React.Component {
render() {
const state = {
show:() => {
console.log('show')
},
hide: () => {
console.log('hide')
}
}
return (
// 透传属性
<OldComponent {...this.props} {...state} />
)
}
}
}
定义子组件
代码语言:txt复制class Hello extends React.Component{
render() {
return <div>
hello
<button onClick={this.props.show}>show</button>
<button onClick={this.props.hide}>hide</button>
</div>
}
}
// loading 函数返回一个函数,参数为 oldComponent
const Com = loading('loading')(Hello)
ReactDOM.render(<Hello></Hello>, document.getElementById('root'))
可以看到子组件中已经可以调用父中的方法了。当然这种方式是使用调用函数形式,我们还可以使用装饰器,如下:
装饰器实现
首先需要安装依赖包,npm i react-app-rewired customize-cra @babel/plugin-proposal-decorators -D
- react-app-rewired 用于我们改写 react 的启动方式
- customize-cra 用于我们插入新的 babel 插件
因为装饰器 js
本身不支持,需要引入插件才能使用
// project/config-overrides.js
const {override, addBabelPlugin} = require('customize-cra')
module.exports = override(
addBabelPlugin([
"@babel/plugin-proposal-decorators", {"version": "legacy"}
])
)
代码语言:txt复制// project/jsconfig.json
{
"compilerOptions": {
"experimentalDecorators": true
}
}
这里的使用也比较简单,只是把 loading
函数的调用改为装饰器,我们可以看到同样的效果
@loading('xxx')
class Hello extends React.Component{
render() {
return <div>
hello
<button onClick={this.props.show}>show</button>
<button onClick={this.props.hide}>hide</button>
</div>
}
}
代码复用
高阶组件的作用其实就是为了组件之间的代码复用,现有的复用方式大体有如下几种:
- 代码直接
copy
- 最
low
的方式
- 最
- 高阶组件
- 抽离公用逻辑,可以新的组件中处理拦截,操作生命周期,拓展导入组件的
props
,逻辑复杂时不易维护
- 抽离公用逻辑,可以新的组件中处理拦截,操作生命周期,拓展导入组件的
- 类继承
- 继承父类,不易拓展,且类组件的性能消耗比较大,因为类组件需要创建类组件的实例,而且不能销毁
- mixins
- 不需要传递状态,操作方便;缺点数据来源不明确,容易被滥用
- hooks
- 现在主流方式,数据来源追溯,逻辑分层清晰,易维护。消耗小,执行完就会被销毁
本节内容不是很多,小编也确实对高阶组件接触不多,如有错误欢迎指正!