高阶组件——基本含义
用于非侵入性的增强组件,在指定组件上利用工厂函数将该组件传给工厂返回一个被增强的组件;
一般来讲,我们将公共的部门抽离出来,用作所有组件可以通用的增强器
高阶组件——扩展render
(1)创建工厂函数
import React from 'react';
/**
* 罗列工厂函数
* WrappedComponent:传入一个react组件
* componetSetting:自定义一个对象传入相应的组件配置
*/
function withHeaders(WrappedComponent,componetSetting) {
/**
* 返回一个代理组件的渲染,而原先的组件黑包裹在了里面,这样我们即使不改变原组件的东西
* 也可以在其外围添加东西
*/
return class HOC extends React.Component {
render() {
return (
<div>
<div>{componetSetting.title}——————的头部</div>
<WrappedComponent {...this.props} />
</div>
)
}
}
}
function withFooters(WrappedComponent,componetSetting) {
return class HOC extends React.Component {
render() {
return (
<div>
<WrappedComponent {...this.props} />
<div>{componetSetting.title}——————的尾部</div>
</div>
)
}
}
}
/**
* 暴露工厂函数
*/
export default {
withHeaders,
withFooters
}
(2)调用工厂函数
import React from 'react';
import factory from "./factory"
const commponetSetting = {
title: "Body测试"
}
class BodyOne extends React.Component {
render() {
return (
<div className="App">
<h3>Body测试</h3>
</div>
)
}
}
export default factory.withHeaders(BodyOne, commponetSetting)
(3)效果
(4)嵌套
import React from 'react';
import factory from "./factory"
const commponetSetting = {
title: "Body测试"
}
class BodyOne extends React.Component {
render() {
return (
<div className="App">
<h3>Body测试</h3>
</div>
)
}
}
export default
factory.withFooters(
factory.withHeaders(BodyOne, commponetSetting),
commponetSetting
);
注意,…this.props将所有的最外部的属性和函数都传进了组件内,所以这样单向通讯是没问题的;
但是用ref拿到的则是被增强的组件而不是原组件,这种需求只能用反向继承实现
高阶组件——劫持props/function
function dataStream(WrappedComponent,componetSetting) {
return class HOC extends React.Component {
newProp={
'username':"增加后的数据",
'handleClick':()=>{
alert("增强后的函数")
}
}
constructor(props){
super(props);
/*
如何代理对象存在则不替换,不存在则替换
*/
Object.keys(this.props).forEach(key => {
if(!this.newProp.hasOwnProperty(key)){
this.newProp[key]=this.props[key]
}
});
}
render() {
return (
/*
传入新的prop对象
*/
<WrappedComponent {...this.newProp} />
)
}
}
}
/**
* 暴露工厂函数
*/
export default {
withHeaders,
withFooters,
dataStream
}
高阶组件——反向继承
反向继承的优点就是可以直接访问到父元素的所有state和方法,相当于代理继承,操作更加自由,而不需总通过代理对象做中转
function oppExtends(WrappedComponent,componetSetting) {
return class HOC extends WrappedComponent {
constructor(props){
}
render() {
return (
super.render()
)
}
}
}