美文网首页
高阶组件

高阶组件

作者: 张_何 | 来源:发表于2022-05-14 16:06 被阅读0次
    • 高阶函数:我们把至少满足以下条件之一的称为高阶函数:
    • 接受一个或多个函数作为输入;
    • 输出一个函数;

    高阶组件

    • 那么什么是高阶组件呢?
    • 高阶组件的英文是Higher-Order Components,简称为 HOC
    • 官方定义是: 高阶组件是参数为组件,返回值为新组件的函数
    • 高阶组件本身不是一个组件,而是一个函数
    • 这个函数的参数是一个组件,返回值也是一个组件
    import React, { PureComponent } from 'react'
    class App extends PureComponent {
      render() {
        return (
          <div>
            "App"
          </div>
        )
      }
    }
    function enhanceComponent(WrappedComponent) {
      class NewComponent extends PureComponent {
        render() {
          return <WrappedComponent />
        }
      }
      NewComponent.displayName = "Kobe";
      return NewComponent;
    }
    const EnhanceComponent = enhanceComponent(App);
    export default EnhanceComponent
    
    • 高阶组件并不是 React API 的一部分,它是基于 React 的组合特性而形成的设计模式
    高阶组件的应用
    props 的增强
    • 假设我们要给一个组件增加一个属性, 由于当前该组件已经在很多地方使用了,那么改的话就要修改好多地方,这个时候就可以定义一个高阶组件
    import React, { PureComponent } from 'react';
    
    // 定义一个高阶组件
    function enhanceRegionProps(WrappedComponent) {
    // props 是传过来的属性, 在返回组件时将传过来的 props 和新增的属性一起传给组件
      return props => { 
        return <WrappedComponent {...props} region="中国"/>  
      }
    }
    
    class Home extends PureComponent {
      render() {
        return <h2>Home: {`昵称: ${this.props.nickname} 等级: ${this.props.level} 区域: ${this.props.region}`}</h2>
      }
    }
    
    class About extends PureComponent {
      render() {
        return <h2>About: {`昵称: ${this.props.nickname} 等级: ${this.props.level} 区域: ${this.props.region}`}</h2>
      }
    }
    
    const EnhanceHome = enhanceRegionProps(Home);
    const EnhanceAbout = enhanceRegionProps(About);
    
    class App extends PureComponent {
      render() {
        return (
          <div>
            App
            <EnhanceHome nickname="coderwhy" level={90}/>
            <EnhanceAbout nickname="kobe" level={99}/>
          </div>
        )
      }
    }
    export default App;
    
    登录鉴权
    • 针对所有要需要登录态的页面进行登录态鉴别,没有就跳登录页, 这里我们就可以使用高阶组件,将所有需要鉴权的页面都使用高阶组件包裹
    import React, { PureComponent } from 'react';
    
    class LoginPage extends PureComponent {
      render() {
        return <h2>LoginPage</h2>
      }
    }
    
    function withAuth(WrappedComponent) {
      const NewCpn = props => {
        const {isLogin} = props;
        if (isLogin) {
          return <WrappedComponent {...props}/>
        } else {
          return <LoginPage/>
        }
      }
    
      NewCpn.displayName = "AuthCpn"
    
      return NewCpn;
    }
    
    // 购物车组件
    class CartPage extends PureComponent {
      render() {
        return <h2>CartPage</h2>
      }
    }
    
    const AuthCartPage = withAuth(CartPage);
    
    export default class App extends PureComponent {
      render() {
        return (
          <div>
            <AuthCartPage isLogin={true}/>
          </div>
        )
      }
    }
    
    生命周期劫持
    import React, { PureComponent } from 'react';
    
    function withRenderTime(WrappedComponent) {
      return class extends PureComponent {
        // 即将渲染获取一个时间 beginTime
        UNSAFE_componentWillMount() {
          this.beginTime = Date.now();
        }
    
        // 渲染完成再获取一个时间 endTime
        componentDidMount() {
          this.endTime = Date.now();
          const interval = this.endTime - this.beginTime;
          console.log(`${WrappedComponent.name}渲染时间: ${interval}`)
        }
    
        render() {
          return <WrappedComponent {...this.props}/>
        }
      }
    }
    
    class Home extends PureComponent {
      render() {
        return <h2>Home</h2>
      }
    }
    
    class About extends PureComponent {
      render() {
        return <h2>About</h2>
      }
    }
    
    const TimeHome = withRenderTime(Home);
    const TimeAbout = withRenderTime(About);
    
    export default class App extends PureComponent {
      render() {
        return (
          <div>
            <TimeHome />
            <TimeAbout />
          </div>
        )
      }
    }
    
    ref 转发
    • 函数式组件由于没有实例,所以无法通过 ref 获取他们的实例,但可以通过 React.forwardRef 拿到
    import React, { PureComponent, forwardRef } from 'react';
    
    // 高阶组件forwardRef
    const Profile = forwardRef(function(props, ref) {
      return <p ref={ref}>Profile</p>
    })
    
    export default class App extends PureComponent {
      constructor(props) {
        super(props);
        this.profileRef = createRef();
      }
    
      render() {
        return (
          <div>
            <Profile ref={this.profileRef} name={"why"}/>
            <button onClick={e => this.printRef()}>打印ref</button>
          </div>
        )
      }
    
      printRef() {
        console.log(this.profileRef.current);
      }
    }
    

    相关文章

      网友评论

          本文标题:高阶组件

          本文链接:https://www.haomeiwen.com/subject/bztmurtx.html