• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

React--高阶组件

武飞扬头像
一如彷徨
帮助2

高阶组件概念

  • 高阶组件的英文是Higher-Order Components,简称为HOC
  • 官方定义: 高阶组件是参数为组件返回值为新组件的函数
  • 高阶组件本质: 一个函数,该函数的参数是一个组件返回值也是一个组件
 import { PureComponent } from 'react'
 
 // 高阶组件
 function hoc(Component) {
   class NewComponent extends PureComponent {
     render(){
       return <Component/>
     }
   }
   return NewComponent
 }
 
 const HelloWorldHoc = hoc(HelloWorld)
 
 class App extends PureComponent {
   render() {
     return (
       <div>
         <HelloWorldHoc/>
       </div>
     )
   }
 }

注意: 高阶组件并不是 React API 的一部分,它是基于 React 的组合特性而形成的设计模式,是 React用于复用组件逻辑的一种高级技巧

应用场景

  • 虽然 Hooks 可以作为高阶组件的替代品,但高阶组件也有实际的应用场景
  • 高阶组件在 React 第三方库中很常见,如 redux 中的 connectreact-router 中的 withRouter

适用场景:

  • 代码复用,逻辑抽象
  • 生命周期劫持
  • props / state 更改

Context共享

  • 增强 props 注入: 当使用 Context.Provider 提供数据时,后代组件一般需要通过赋值contextType,但为了避免有多个 context 一起使用,这时需要 Context.Consumer 进行包裹消费数据
 class App extends PureComponent {
   render() {
     return (
       <div>
         <ThemeContext.Provider value={{ color: 'red', size: 30 }}>
           <Product/>
         </ThemeContext.Provider>
       </div>
     )
   }
 }
  • 假如每个消费数据的组件都使用 Consumer,会显得代码很繁琐,这时候可以使用高阶组件解决
 function withTheme(OriginComponent) {
   // 这里其实返回一个函数组件
   return (props) => {
     // 组件的渲染内容
     return (
       <ThemeContext.Consumer>
         {
           value => <OriginComponent {...value} {...props}/>
         }
       </ThemeContext.Consumer>
     )
   }
 }
 
 export default withTheme
 class Product extends PureComponent {
   render() {
     const { color, size } = this.props
     return (
       <h2>Product:{color}-{size}</h2>
     )
   }
 }
 // 使用高阶组件进行包裹,就可以获取到外部提供的数据
 export default withTheme(Product)

登录鉴权

  • 在访问首页之前都需要先判断 token 是否有效,对于这样需要判断的组件来说,可以使用高阶组件封装
 function loginAuth(OriginComponent) {
   return props => {
     const token = localStorage.getItem('token')
     if(token) return <OriginComponent {...props}/>
     return <h2>请先登录再查看~</h2>
   }
 }
 
 export default loginAuth

生命周期劫持

  • 当需要计算一个组件从挂载到渲染完成共花费多少时间,可以对组件的生命周期函数添加对应的处理逻辑
 function logRenderTime(OriginComponent) {
   return class extends PureComponent {
     constructor() {
       super()
       this.beginTime = new Date().getTime()
     }
 
     componentDidMount() {
       this.endTime = new Date().getTime()
       const interval = this.endTime - this.beginTime
       console.log(`当前${OriginComponent.name}组件花费了${interval}ms`);
     }
     render(){
       return <OriginComponent {...this.props}/>
     }
   }
 }
 
 export default logRenderTime

高阶组件意义

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

早期的 React 有提供组件之间的一种复用方式是 mixin,目前已不再建议使用

  • Mixin 可能会相互依赖,相互耦合,不利于代码维护
  • 不同的 Mixin 中的方法可能会相互冲突
  • Mixin 非常多时,组件处理起来比较麻烦,甚至做针对性处理,会给代码造成滚雪球式的复杂性

高阶组件的缺陷:

  • 需要在原组件上进行包裹或嵌套,如果大量使用会产生非常多的嵌套,让调试变得困难
  • 传递给被包裹组件的 props 容易和被包裹后的组件重名,进而被覆盖

高阶组件的优点:

  • 逻辑复用、不影响被包裹组件的内部逻辑

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgbbafh
系列文章
更多 icon
同类精品
更多 icon
继续加载