阅读 136

ReactNative进阶篇-高阶组件

1. 概念

很多情况下,需要给多个组件添加或者修改一些特定的props,或者在所有组件基础上加个水印等等。而如果这个功能如果是针对多个组件的,每一个组件都写一套相同的代码,显得不是很明智,所以就可以考虑使用高阶组件。

ReactNative的高阶组件也叫HOC(全称Higher-order component),构建方式主要有属性代理反向继承。主要用于:

  • 组件代码复用,代码模块化
  • 增删改props
  • 渲染劫持
  • ……

所以高阶组件经常作为一个函数,且该函数接受一个组件作为参数,并返回一个新的组件。

2. 使用

2.1 组件代码复用,代码模块化

下面是一个简单的高阶组件,给传进去的组件前面加了一个固定的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 )
2.2 增删改Props

也可以在基础上加入特定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
}
2.3 渲染劫持

在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 方法
 static ABC(){
        return 'abc'
    }

# 高阶组件内部
NewComponent.ABC = WrappedComponent.ABC

3. 属性代理与反向继承

对于函数内部高阶组件的生成主要由以下两种:

  • 属性代理:高阶组件通过包裹传进来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 
}

属性代理和反向继承主要的区别是

  • 属性代理:灵活操作组件的props,如上述的增删改props,再把props传给组件。
  • 反向继承:拦截生命周期、state、渲染过程。因为继承了传进来的组件,如果新组件写了componentDidMount等方法,会覆盖掉原方法;也可以在外部组件调用被继承组件的方法,如super.render();

4. 总结

这篇文章主要讲解了HOC的概念和使用思路,需要注意的是,在创建HOC的过程中尽量不要改变原始组件,而是使用组合的方式。HOC的实际使用场景要比现在讲的还要多,例如页面权限管理、数据组装关联、监控日志打印、埋点上报等等,灵活运用好HOC能够对RN的架构逻辑起到很好的帮助与扩展。

参考

React高阶组件中文文档
React Native高阶组件(HOC)模型理论与实践
React-Native 高阶组件

作者:Fat_L

原文链接:https://www.jianshu.com/p/c225fe688014

文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐