在React组件的构建过程中,常常有这样的场景,有一类功能需要被不同的组件公用。(React 中用于重用组件逻辑的高级技巧)
HOC--参数是组件同时返回值也是组件
HOC不仅仅是一个方法,确切说应该是一个组件工厂,获取低阶组件(功能较少),生成高阶组件(添加多个组件复用的功能)
应用场景:
需要代码重用时, react如果有多个组件都用到了同一段逻辑
, 这时,就可以把共同的逻辑部分提取出来,利用高阶组件的形式将这段逻辑整合到每一个组件中, 从而减少代码的逻辑重复
例子:
比如在多个函数中我们都想使用一个相同的方法。这个方法就是自动发出一段异步请求 并且把请求成功的数据赋值给一个state在页面展示。
那么传统方式我们就需要把这个请求在每个组件中都是用一次 组件少了可以。但是组件变多就很麻烦 那么我们就需要想办法解决这个重复的代码 所以我们可以使用HOC来进行组件中公共内容的复用
大家发现下面的例子 这个请求可能会在多个组件都要使用 那么我们可以把他设置成一个HOC
import axios from 'axios'
import React, { Component } from 'react'
export default class two extends Component {
state={
text:""
}
// 发送请求
async componentDidMount (){
let {data}= await axios({url:"/api/data/cityinfo/101320101.html"})
// 把数据赋值给state 并且在下方展示
this.setState({
text:data.weatherinfo.city
})
}
render() {
return (
<div>
{this.state.text}
</div>
)
}
}
HOC高阶组件创建
1.新建withxxx文件 用来容纳HOC(高阶组件明明规则 是withxxx 比如withRouter)
// HOC本质就是一个函数
export default ()=>{
}
2.使用HOC 在需要服用的组件中把刚才封装的HOC引用使用
import axios from 'axios'
import React, { Component } from 'react'
// 1.引用高阶组件
import withLink from "./withLink.js"
// 2.修改暴漏在最下面
class two extends Component {
state={
text:""
}
async componentDidMount (){
let {data}= await axios({url:"/api/data/cityinfo/101320101.html"})
this.setState({
text:data.weatherinfo.city
})
}
render() {
return (
<div>
{this.state.text}
</div>
)
}
}
// 3.把当前组件当成函数的实参传入进去(因为高阶组件参数是一个组件)
export default withLink(two)
3.在高阶组件中设置行参接受传递进来的组件并且返回一个组件
// HOC本质就是一个函数
import React from "react"
// 设置行参接受(首字母要大写)
export default (Component)=>{
// 并且返回值函数一个组件(组件可以是函数组件也可以是类组件)
return class withLinkComponent extends React.Component{
render(){
return (
<>
</>
)
}
}
}
4.移植逻辑
// HOC本质就是一个函数
import React from "react"
import axios from "axios"
// 设置行参接受(首字母要大写)
export default (Component) => {
// 并且返回值函数一个组件(组件可以是函数组件也可以是类组件)
return class withLinkComponent extends React.Component {
// 把之前的逻辑放置进来
state = {
text: ""
}
async componentDidMount() {
let { data } = await axios({ url: "/api/data/cityinfo/101320101.html" })
this.setState({
text: data.weatherinfo.city
})
}
// 把之前的逻辑放置进来
render() {
return (
<>
{/* 把数据传递出去 */}
<Component {...this.state}></Component>
</>
)
}
}
}
组件中使用
import axios from 'axios'
import React, { Component } from 'react'
// 1.引用高阶组件
import withLink from "./withLink.js"
// 2.修改暴漏在最下面
class two extends Component {
render() {
return (
<div>
{/* 组件内使用高阶组件的数据 */}
{this.props.text}
</div>
)
}
}
// 3.把当前组件当成函数的实参传入进去(因为高阶组件参数是一个组件)
export default withLink(two)
高阶组件之反向继承
HOC的反向继承 说的简单点就是渲染劫持 在使用HOC的时候可以进行一个高阶组件中的条件渲染