React 学习笔记二 - HOC 高阶组件理解

官方定义

高阶组件(HOC)是 React 中用于复用组件逻辑的一种高级技巧。HOC 自身不是 React API 的一部分,它是一种基于 React 的组合特性而形成的设计模式。

HOC 是单词 Heigher Order Component 缩写

具体而言,高阶组件是参数为组件,返回值为新组件的函数。

const EnhancedComponent = higherOrderComponent(WrappedComponent);

从官方定义中,我们可以抽取以下重点:

  • 高阶组件就是一个函数.
  • 此函数接受一个组件作为参数.
  • 此函数返回一个组件.
  • 逻辑复用.或者说组件的功能扩展.

高阶组价,接受一个构造函数,返回一个构造函数. 所以,高阶组件就是一个概念. 它本质上也是高阶函数.

react-redux 里面的 connect 函数,就是一个高阶组件.

高级组件就是一个函数,接受一个一个组件(函数),返回一个新组件(函数)

理解高阶组件.

既然高阶组件,本质上是一个函数.那么我就给它一个组件作为入参,在返回一个组件即可.

import React, { useState } from 'react'
import './App.css';
/**
 * 
 * 官方定义高阶组件(HOC)是 React 中用于**复用组件逻辑**的一种高级技巧。HOC 自身不是 React API 的一部分,它是一种基于 React 的组合特性而形成的设计模式。
   HOC 是单词 Heigher Order Component 缩写
   具体而言,高阶组件是参数为组件,返回值为新组件的函数。
 * 
 * 
 */

function HelloComponent(props) {
  return (
    

我是一个定义的函数式组件 {props.title}

) } // 高阶组件就是一个函数,接收一个组件,返回一个[新]的组件. const withComponent = (Component) => { return function WrapperComponent() { const [title, setTitle] = useState('这是由内部组件 WrapperComponent 传递过来的 title') const changeTitle = () => { setTitle("这是新的 title") } return ( ) } } // 传入一个HelloComponent,作为入参 // 返回一个HocComponent作为新的组件 const HocComponent = withComponent(HelloComponent) function App() { return (

Hello HOC - Highter Order Component

); } export default App;

可以正常工作.

![高阶组件简单使用images.jianshu.io/upload_images/2701794-d79d78664a4895aa.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


将逻辑复用(功能扩展)逻辑设定在高阶组件中.

上述例子,仅演示了高阶组件的用法和原理.

这次,我们把逻辑复用和功能扩展加上去.

这么一个例子

  • 有两组件. FooBar.
  • FooBar 组件的功能就是在屏幕视口宽度发生改变是,动态的把宽度数值显示出来.

import React from 'react'
import './App.css';
/**
 * 
 * 官方定义高阶组件(HOC)是 React 中用于**复用组件逻辑**的一种高级技巧。HOC 自身不是 React API 的一部分,它是一种基于 React 的组合特性而形成的设计模式。
   HOC 是单词 Heigher Order Component 缩写
   具体而言,高阶组件是参数为组件,返回值为新组件的函数。
 * 
 * 
 */

class Foo extends React.PureComponent {
  state = {
    sw: document.documentElement.clientWidth
  }

  componentDidMount () {
    window.addEventListener('resize', () => {
      this.setState(() => ({ sw: document.documentElement.clientWidth }))
    }, false)
  }

  componentWillUnmount () {
    window.removeEventListener('resize')
  }

  render () {
    return (
      

当前的屏幕宽度为:{this.state.sw}

) } } class Bar extends React.PureComponent { state = { sw: document.documentElement.clientWidth } componentDidMount () { window.addEventListener('resize', () => { this.setState(() => ({ sw: document.documentElement.clientWidth })) }, false) } componentWillUnmount () { window.removeEventListener('resize') } render () { return ( ) } } function App () { return (

Hello HOC - Highter Order Component

); } export default App;

效果如图:

[图片上传失败...(image-c468a2-1642682879317)]

功能确实实现了.但是两组件除了渲染的位置,其他地方都是一致的.

Vue中,我们可以使用 mixins 来解决组件间逻辑重复定义的问题.

state , componentDidMount, componentWillUnmount 逻辑重复.

React 中,我们就可以使用 Highter Order Component 高阶组件的方式,来抽取组件重复定义的逻辑部分.

// 定义一个高阶组件函数,来抽取逻辑重复的位置,提高逻辑复用.
const withResize = (Component) => {
    //xxxxx
}

具体代码如下:

import React from 'react'
import './App.css';
/**
 * 
 * 官方定义高阶组件(HOC)是 React 中用于**复用组件逻辑**的一种高级技巧。HOC 自身不是 React API 的一部分,它是一种基于 React 的组合特性而形成的设计模式。
   HOC 是单词 Heigher Order Component 缩写
   具体而言,高阶组件是参数为组件,返回值为新组件的函数。
 * 
 * 
 */

class Foo extends React.PureComponent {
  // state = {
  //   sw: document.documentElement.clientWidth
  // }

  // componentDidMount () {
  //   window.addEventListener('resize', () => {
  //     this.setState(() => ({ sw: document.documentElement.clientWidth }))
  //   }, false)
  // }

  // componentWillUnmount () {
  //   window.removeEventListener('resize')
  // }

  render () {
    return (
      

当前的屏幕宽度为:{this.props.sw}

) } } class Bar extends React.PureComponent { // state = { // sw: document.documentElement.clientWidth // } // componentDidMount () { // window.addEventListener('resize', () => { // this.setState(() => ({ sw: document.documentElement.clientWidth })) // }, false) // } // componentWillUnmount () { // window.removeEventListener('resize') // } render () { return ( ) } } // 定义一个高阶组件函数,来抽取逻辑重复的位置,提高逻辑复用. const withResize = (Component) => { return class WrappedComponent extends React.PureComponent { //#region 抽离组件通用的逻辑部分 state = { sw: document.documentElement.clientWidth } componentDidMount () { window.addEventListener('resize', () => { this.setState(() => ({ sw: document.documentElement.clientWidth })) }, false) } componentWillUnmount () { window.removeEventListener('resize') } //#endregion render () { // 将需要的数据以 props 的方式传递给被包装的组件 return } } } const FooWithResize = withResize(Foo) const BarWithResize = withResize(Bar) function App () { return (

Hello HOC - Highter Order Component

将通用逻辑抽离,以便复用!

{/* */}
); } export default App;
  • 将通用逻辑从 FooBar 组件中抽离.起到逻辑复用的作用.
  • FooBar 需要的数据以 props 的形式传入即可.
高阶组件抽取通用逻辑以便复用.gif

效果和上述是一致的.


总结

  • 高阶组件就是一个函数仅此而已(javascript中不就是函数和对象吗?)
  • 高阶组件接受一个组件(可以是函数组件,也可以是class 组件)作为参数(普通函数,构造函数).
  • 返回一个新组件(可以是函数组件,也可是 class 组件),返回一个普通函数或者是构造函数.
  • 所以高阶组件也是一个高阶函数.
  • 将通用的逻辑抽离在高阶组件中,已达到复用的目的.

码云地址

你可能感兴趣的:(React 学习笔记二 - HOC 高阶组件理解)