很多情况下,需要给多个组件添加或者修改一些特定的props,或者在所有组件基础上加个水印等等。而如果这个功能如果是针对多个组件的,每一个组件都写一套相同的代码,显得不是很明智,所以就可以考虑使用高阶组件。
ReactNative的高阶组件也叫HOC(全称Higher-order component),构建方式主要有属性代理和反向继承。主要用于:
所以高阶组件经常作为一个函数,且该函数接受一个组件作为参数,并返回一个新的组件。
下面是一个简单的高阶组件,给传进去的组件前面加了一个固定的Text组件。
# 定义
export const HocComponent = (param) => (WrappedComponent) => {
class NewComponent extends React.Component {
render() {
return(
<View>
<Text>我是高阶组件,传进来参数是:{JSON.stringify(param)}</Text>
<WrappedComponent {...this.props}/>
</View>
)
}
}
return NewComponent
}HocComponent 是一个函数,param是需要传入组件的参数,WrappedComponent是传入的组件,NewComponent就是传入参数后生成的新的组件。 使用方式推荐用装饰器语法, 如下图就可以给TestComp和TestComp2组件传入参数都加上一个Text组件。
# 装饰器调用
@HocComponent({name:'zhangsan'})
export class TestComp extends React.Component<IProps> {
...
}
# 装饰器调用
@HocComponent({name:'lisi'})
export class TestComp2 extends React.Component<IProps> {
...
}
# 函数调用 ( HocComponent改成返回<NewComponent/>)
const TestComp = HocComponent({name:'zhangsan'})(TestComp )也可以在基础上加入特定props,例如在高阶组件内部自定义一个颜色主题themeType,这样就可以在新返回的组件通过this.props.themeType获取当前的颜色主题。
export default (Comp)=>{
class newCom extends React.Component{
const newProps = {
...this.props,
themeType:'dark'
}
render() {
return <Comp {...newProps}/>
}
}
return newCom
}在render方法里控制显示渲染逻辑,下面是一个例子。 当属性this.props.loading为true时显示加载组件,当属性this.props.data数据为空时显示空白组件,正常则直接显示渲染传入的<Comp/>组件。
const HocComponent = (WrappedComponent)=>{
newComp extends WrappedComponent {
render(){
if(this.props.loading){
return <View><Text>加载中</Text></View>
}
if(this.props.data.length>0){
return <View><Text>暂无数据</Text></View>
}
return super.render();
}
}
return newComp
}需要注意的是:
当使用高阶组件包装组件,原始组件被容器组件包裹,也就意味着新组件会丢失原始组件的所有静态方法。解决这个问题的方法就是,将原始组件的所有静态方法全部拷贝给新组件:
# 普通组件内部定义了 static 方法
static ABC(){
return 'abc'
}
# 高阶组件内部
NewComponent.ABC = WrappedComponent.ABC对于函数内部高阶组件的生成主要由以下两种:
包裹传进来React组件进行操作;继承于被包裹的React组件进行操作。 上面所说的(1)(2)主要是属性代理的使用方式,(3)反向继承的案例,下面是反向继承的详细案例。
const HocComponent = (WrappedComponent)=>{ newComp extends WrappedComponent { // 此处重写了父类的方法父类就不会再执行 componentDidMount() componentDidMount() { console.log('1') // 修改父类的 state this.setState({ result: '通过高阶组件(反向继承方式)创建的组件' }) } render(){ return super.render(); } } return newComp }属性代理和反向继承主要的区别是
这篇文章主要讲解了HOC的概念和使用思路,需要注意的是,在创建HOC的过程中尽量不要改变原始组件,而是使用组合的方式。HOC的实际使用场景要比现在讲的还要多,例如页面权限管理、数据组装关联、监控日志打印、埋点上报等等,灵活运用好HOC能够对RN的架构逻辑起到很好的帮助与扩展。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。