微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

高阶组件Higher Order Component

高阶组件(HOC)是React开发中的特有名词,一个函数返回一个React组件,指的就是一个React组包裹着另一个React组件。可以理解为一个生产React组件的工厂。

有两种类型的HOC:

  1. Props Proxy(pp) HOC对被包裹组件WrappedComponent的props进行操作。
  2. Inherbitance Inversion(ii)HOC继承被包裹组件WrappedComponent

Props Proxy

一种最简单的Props Proxy实现

function ppHOC(WrappedComponent) {  
  return class PP extends React.Component {    
    render() {      
      return <WrappedComponent {...this.props}/>    
    }  
  } 
}

这里的HOC是一个方法,接受一个WrappedComponent作为方法的参数,返回一个PP class,renderWrappedComponent。使用的时候:

const ListHOCInstance = ppHOC(List)
<ListHOCInstance name='instance' type='hoc' />

这个例子中,我们将本应该传给List的props,传给了ppHoc返回的ListHOCInstance(PP)上,在HOC内部我们将PP的参数直接传给ListWrappedComponent)。这样的就相当于在List外面加了一层代理,这个代理用于处理即将传给WrappedComponent的props,这也是这种HOC为什么叫Props Proxy。

在pp中,我们可以对WrappedComponent进行以下操作:

  1. 操作props(增删改)
  2. 通过refs访问到组件实例
  3. 提取state
  4. 用其他元素包裹WrappedComponent

操作props

比如添加新的props给WrappedComponent

const isLogin = false;

function ppHOC(WrappedComponent) {
  return class PP extends React.Component {
    render() {
      const newProps = {
        isNew: true,login: isLogin
      }
      return <WrappedComponent {...this.props} {...newProps}/>
    }
  }
}

WrappedComponent组件新增了两个props:isNew和login。

通过refs访问到组件实例

function refsHOC(WrappedComponent) {
  return class RefsHOC extends React.Component {
    proc(wrappedComponentInstance) {
      wrappedComponentInstance.method()
    }

    render() {
      const props = Object.assign({},this.props,{ref: this.proc.bind(this)})
      return <WrappedComponent {...props}/>
    }
  }
}

Ref 的回调函数会在 WrappedComponent 渲染时执行,你就可以得到WrappedComponent的引用。这可以用来读取/添加实例的 props ,调用实例的方法

不过这里有个问题,如果WrappedComponent是个无状态组件,则在proc中的wrappedComponentInstance是null,因为无状态组件没有this,不支持ref。

提取state

你可以通过传入 props 和回调函数把 state 提取出来,

function ppHOC(WrappedComponent) {
  return class PP extends React.Component {
    constructor(props) {
      super(props)
      this.state = {
        name: ''
      }

      this.onNameChange = this.onNameChange.bind(this)
    }
    onNameChange(event) {
      this.setState({
        name: event.target.value
      })
    }
    render() {
      const newProps = {
        name: {
          value: this.state.name,onChange: this.onNameChange
        }
      }
      return <WrappedComponent {...this.props} {...newProps}/>
    }
  }
}

使用的时候:

class Test extends React.Component {
    render () {
        return (
            <input name="name" {...this.props.name}/>
        );
    }
}

export default ppHOC(Test);

这样的话,就可以实现将input转化成受控组件。

用其他元素包裹 WrappedComponent

这个比较好理解,就是将WrappedComponent组件外面包一层需要的嵌套结构

function ppHOC(WrappedComponent) {
  return class PP extends React.Component {
    render() {
      return (
        <div style={{display: 'block'}}>
          <WrappedComponent {...this.props}/>
        </div>
      )
    }
  }
}

Inheritance Inversion(反向继承)

先看一个反向继承(ii)的

原文地址:https://www.jb51.cc/react/302224.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐