React的高阶组件

高阶组件(Higher-Order Components)就是一个就是一个没有副作用的纯函数,且该函数接受一个组件作为参数,并返回一个新的组件。

 

实现步骤
  1. 首先创建一个函数
  2. 指定函数参数,参数应该以大写字母开头
  3. 在函数内部创建一个类组件或函数组件,提供复用的状态逻辑代码,并返回
  4. 在该组件中,渲染参数组件,同时将状态通过prop传递给参数组件(可选,如有)
  5. 调用该高阶组件,传入要增强的组件,通过返回值拿到增强后的组件,并将其渲染到页面
作用:
  1. 进行权限控制
  2. 路由限制
  3. 访问统计
  4. 统一布局

高阶组件的应用

props 的增强
  • 假设我们要给一个组件增加一个属性, 由于当前该组件已经在很多地方使用了,那么改的话就要修改好多地方,这个时候就可以定义一个高阶组件
复制import React, { PureComponent } from 'react';

// 定义一个高阶组件
function wrap(WrappedComponent) {
  // props 是传过来的属性, 在返回组件时将传过来的 props 和新增的属性一起传给组件
  return props => {
    return <WrappedComponent {...props} region="中国" />
  }
}
// Beijing 和 Taiwan有共同的一个属性region都属于中国
class Beijing extends PureComponent {
  render() {
    return <h2> 北京在北方。 所属国家: {this.props.region}</h2>
  }
}
class Taiwan extends PureComponent {
  render() {
    return <h2> 台湾在南方。 所属国家: {this.props.region}</h2>
  }
}

const BeijingEx = wrap(Beijing);
const TaiwanEx = wrap(Taiwan);

class App extends PureComponent {
  render() {
    return (
      <div>
        {/* <Beijing region="中国"/> */}
        {/* <Taiwan region="中国"/> */}
        <BeijingEx />
        <TaiwanEx />
      </div>
    )
  }
}
export default App;
登录鉴权
  • 针对所有要需要登录态的页面进行登录态鉴别,没有就跳登录页, 这里我们就可以使用高阶组件,将所有需要鉴权的页面都使用高阶组件包裹
复制import React, { PureComponent } from 'react';

class LoginPage extends PureComponent {
  render() {
    return <h2>LoginPage</h2>
  }
}
function withAuth(WrappedComponent) {
  return props => {
    if (checkToken()) { // 如果已经登录过,则跳转到功能页面,否则跳转到登录页面
      return <WrappedComponent {...props} />
    }
    return <LoginPage />
  }
}
// 购物车组件
class Cart extends PureComponent {
  render() {
    return <h2>Cart</h2>
  }
}
const AuthCart = withAuth(Cart);
export default class App extends PureComponent {
  render() {
    return (
      <div>
        <AuthCart 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);
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值