React 高阶组件

480 阅读2分钟

React 高阶组件

什么是高阶组件

高阶组件的定义:高阶组件是一个函数,它接受一个组件作为参数,返回一个新的组件,这就是高阶组件。 高阶组件把一个组件转化为另一个组件主要就是增强原来的组件,逻辑复用等。

高阶组件使用及编写结构

在介绍高阶组件怎么写之前先看一下怎么用,有下面两种方式:

  • 作为函数调用
function App() {}

export default observer(App)
  • 装饰器模式
@observer
class App extends React.Component {}

类的装饰器是ES6中新增的内容,装饰器的行为就是下面这样

@decorator
class A {}

// 等同于

class A {}
A = decorator(A) || A;

有的高阶组件还可以传参数

function App() {}

export default connect(mapPropsToState)(App)

有了上面的使用,我们基本上可以知道高阶组件的编写结构了

function observer(WrappedComponent) {
  return class extends React.Component {

    /**  编写逻辑 **/

    render() {
      <WrappedComponent {...this.props} />
    }
  }
}

function observer(WrappedComponent) {
  return (props) => <WrappedComponent {...props} />
}

有些高阶组件需要参数,比如 react-redux 的 connect

connect(mapStateToProps)(Component)

对于这样的高阶组件我们需要再抽象一层

function connect (mapStateToProps){

    return function wrapWithConnect(WrappedComponent) {
      
      return function ConnectFunction(props){

      }
    }
}

高阶组件的实现

属性代理

给组件增加新的属性,比如,mobx-react 的 inject 组件

const inject = (...storeNames) => component => {
  const Injector = React.forwardRef((props, ref) => {
    const context = useContext(MobXProviderContext)

    const newProps = {
      ...props,
      ...context // 给组件新增的属性
    }
    if (ref) {
      newProps.ref = ref
    }
    return React.createElement(component, newProps)
  })

  return Injector
}

劫持渲染

比如 mobx-react 的 observer 就是劫持了组件的渲染,使其变为可自动更新的组件

observer 实现的思路如下, 我们简化流程,主要目的是说明高阶组件的编写

function observer(WrappedComponent) {

  // 针对类组件
  if (component.prototype && component.prototype.isReactComponent) {
    return makeClassComponentObserver(WrappedComponent)
  }
  
  function makeClassComponentObserver(componentClass) {
    const target = componentClass.prototype
    const baseRender = target.render

    // 劫持了原组件的render方法,使其变为响应式
    target.render = function() {
      return makeComponentReactive.call(this, baseRender) // makeComponentReactive 方式的实现省略...
    }

    return componentClass
  }
}

总结

上面两种高阶组件的实现方式只是起到抛砖引玉的作用,高阶组件可以做很多事情,比如:复用逻辑、强化props、增强功能、赋能组件、控制渲染等。