- 高阶函数:我们把至少满足以下条件之一的称为高阶函数:
高阶组件
- 高阶组件的英文是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);
}
}
网友评论