文章

React高阶组件HOC

React高阶组件HOC

React 的高阶组件(Higher-Order Component,简称 HOC)是一种用于复用组件逻辑的高级技巧,它本质上是一个接受组件并返回新组件的函数。HOC 并不是 React 的一部分,而是 React 组合特性的一种模式。

1. HOC 的定义

高阶组件是一个函数,接受一个组件作为参数,并返回一个增强后的新组件。例如:

1
2
3
4
5
6
7
function withHOC(WrappedComponent) {
  return class extends React.Component {
  render() {
    return  <WrappedComponent {...this.props} />;
    }
  };
}

2. HOC 的工作原理

HOC 通过创建一个包装组件,来封装被包裹的组件 WrappedComponent。包装组件可以通过修改、扩展或拦截 props 的方式,来实现对原组件的增强。HOC 可以做的事情包括:

  • 修改 props:可以在新组件中添加额外的 props 或者修改已有的 props。
  • 抽离公共逻辑:实现多个组件之间的逻辑复用。
  • 控制渲染:可以基于特定条件,决定是否渲染原组件。

3. HOC 的使用场景

(1)逻辑复用

如果多个组件有相似的逻辑(比如权限校验、数据获取、事件监听等),可以将这些逻辑抽离到 HOC 中,以实现复用。这样可以减少代码冗余,让组件更加专注于展示逻辑。

1
2
3
4
5
6
7
8
9
10
11
    function withAuthorization(WrappedComponent) {
      return class extends React.Component {
        componentDidMount() {
          // 权限校验逻辑
        }
        render() {
          // 如果通过校验则渲染组件
          return  <WrappedComponent {...this.props} />;
        }
      };
    }

(2)操作 props

HOC 可以通过操作 props 来增强组件的功能。比如给组件注入默认值、增加样式等。

1
2
3
4
5
6
7
    function withDefaultProps(WrappedComponent, defaultProps) {
      return class extends React.Component {
        render() {
          return  <WrappedComponent {...defaultProps} {...this.props} />;
        }
      };
    }

(3)渲染劫持

可以通过条件判断控制渲染,达到控制子组件展示内容的目的。例如,一个加载状态的 HOC:

1
2
3
4
5
6
7
8
    function withLoading(WrappedComponent) {
      return class extends React.Component {
        render() {
          if (this.props.isLoading) return <div>Loading...</div>;
          return  <WrappedComponent {...this.props} />;
        }
      };
    }  

(4)数据处理

HOC 可以作为一种数据处理层,将数据处理的逻辑与 UI 组件分离。例如,一个数据转换的 HOC:

1
2
3
4
5
6
7
8
9
10
11
    function withTransformedData(WrappedComponent) {
      return class extends React.Component {
        transformData(data) {
          // 数据转换逻辑
        }
        render() {
          const transformedData = this.transformData(this.props.data);
          return  <WrappedComponent {...this.props} data={transformedData} />;
        }
      };
    }

4. 使用 HOC 的注意事项

  • 不要改变原始组件。HOC 应该返回一个新的组件,而不是修改传入的组件本身。
  • 复制静态方法。高阶组件会屏蔽原组件的静态方法,可以通过 hoist-non-react-statics 库来解决此问题。
  • 避免嵌套过深。多个 HOC 嵌套会导致代码复杂度上升,阅读和调试变得困难。

5. HOC 与 React Hooks 的对比

自 React 16.8 引入 Hooks 后,HOC 的使用场景有所减少。许多逻辑复用的场景可以通过 useEffect、useContext 等 Hook 进行管理。不过 HOC 依然适用于某些复合场景,尤其是需要对组件进行包装和增强的情况下。

本文由作者按照 CC BY 4.0 进行授权