706 字
4 分钟
04.高阶组件
2025-03-28

高阶组件的英文是 Higher-Order Components,简称为 HOC;

官方的定义:高阶组件是参数为组件,返回值为新组件的函数

根据上文:

  • 高阶组件本身不是一个组件,而是一个函数;

  • 这个函数的参数是一个组件,返回值也是一个组件。

function enhanceComponent(WrappedComponent) {
    return class NewComponent extends PureComponent {
        render() {
            return <WrappedComponent/>
        }
    }
}
  • 高阶组件并不是React API的一部分,它是基于React的组合特性而形成的设计模式;

  • 高阶组件在一些React第三方库中非常常见:

比如 redux 中的 connect 和 react-router 中的 withRouter。

高阶组件的一些应用#

props增强#

使用高阶组件可以对多个组件添加多个相同的 props 参数:

import React, { PureComponent } from 'react'

class App extends PureComponent {
  render() {
    return (
      <div>
        App
        <EnhanceHome name='Sytus' age={17}></EnhanceHome>
        <EnhanceAbout name='Ram' age={20}></EnhanceAbout>
      </div>
    )
  }
}

class Home extends PureComponent {
  render() {
    return (
      <div>
        <h2>Home: {this.props.name + ' ' + this.props.age + ' ' + this.props.region}</h2>
      </div>
    )
  }
}

const EnhanceHome = enhanceRegionProps(Home)

class About extends PureComponent {
  render() {
    return (
      <div>
        <h2>About: {this.props.name + ' ' + this.props.age + ' ' + this.props.region}</h2>
      </div>
    )
  }
}

const EnhanceAbout = enhanceRegionProps(About)

function enhanceRegionProps(WrappedComponent) {
  return props => {
    return <WrappedComponent {...props} region='China'/>
  }
}
export default App

渲染判断鉴权#

使用高阶组件可以对具有判断需求的组件进行处理:

import React, { PureComponent } from 'react'

function withAuth(WrappedComponent) {
  return props => {
    const { isLogin } = props
    if (isLogin) {
      return <WrappedComponent {...props} />
    } else {
      return <LoginPage></LoginPage>
    }
  }
}

export default class App extends PureComponent {
  render() {
    return (
      <div>
        <AuthCartPage isLogin={false}></AuthCartPage>
      </div>
    )
  }
}

class CartPage extends PureComponent {
  render() {
    return (
      <div>
        <h2>CartPage</h2>
      </div>
    )
  }
}

const AuthCartPage = withAuth(CartPage)

class LoginPage extends PureComponent {
  render() {
    return (
      <div>
        <h2>LoginPage</h2>
      </div>
    )
  }
}

生命周期劫持#

在面对一些需求时,我们可能需要在多个生命周期中进行处理数据,比如计算 render 函数的渲染时间:

import React, { PureComponent } from 'react'

function withRenderTime(WrappedComponent) {
  return class NewComponent extends PureComponent {
    UNSAFE_componentWillMount() {
      this.beginTime = Date.now()
    }

    componentDidMount() {
      this.endTime = Date.now()
      console.log(WrappedComponent.name, this.endTime - this.beginTime + 'ms');
    }

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

class App extends PureComponent {
  render() {
    return (
      <div>
        App
        <TimeHome name='Sytus' age={17}></TimeHome>
        <TimeAbout name='Ram' age={20}></TimeAbout>
      </div>
    )
  }
}

class Home extends PureComponent {
  render() {
    return (
      <div>
        <h2>Home</h2>
      </div>
    )
  }
}

class About extends PureComponent {
  render() {
    return (
      <div>
        <h2>About</h2>
      </div>
    )
  }
}

const TimeHome = withRenderTime(Home)
const TimeAbout = withRenderTime(About)

export default App

高阶组件的意义#

高阶组件可以针对某些 React 代码进行更加优雅的处理。

但 HOC 也有自己的一些缺陷:

  1. HOC 需要在原组件上进行包裹或嵌套,如果大量使用 HOC,将会产生非常多的嵌套,这让调试变得非常困难;

  2. HOC 可以劫持 props,在不遵守约定的情况下也可能造成冲突。

Hooks 的出现,是开创性的,它解决了 React 之前存在的问题,比如 this 指向问题,比如 HOC 的嵌套复杂问题等等。

04.高阶组件
https://sytusramlethal.github.io/posts/04高阶组件/
作者
Sytus Ramlethal
发布于
2025-03-28
许可协议
CC BY-NC-SA 4.0