二、高阶组件HOC
HOC是react对组件复用部分进行抽离的高级技术,HOC是一种设计模式
HOC是一个函数,他接受一个组件并且返回一个组件,接收的是一个可复用组价,通过对他的功能增强,返回的新组件拥有更高的专用性,同时又不会影响可复用组件
高阶组件实际上是一个函数,这个函数接收一个组件,进行增强功能后在导出一个组件
HOC与mixin
结果来看,HOC达到了和mixins相同的作用,HOC是将中间进行一层层的包装进行增强,而mixin则是将方法和属性混入在组件中
对于被包裹的组件时不会感知到高阶组件的存在,而高阶组件返回的组件会在原来的组件之上具有功能增强的效果,而Mixin这种混入的模式,会给组件不断增加新的方法和属性,组件本身不仅可以感知,甚至需要做相关的处理(例如命名冲突、状态维护),一旦混入的模块变多时,整个组件就变的难以维护
好处
将一些通用的逻辑封装在高阶组件中,当你将一个组件传给他,他吐给你的是一个拥有这些处理逻辑的新组件,他就相当于手机组装的流水线,
通过不同的搭配他也能实现不同的功能,因为是一层层的包装,完全可以删除某一层,或者添加某一层来增删一些功能
模板
需要进行增强的组件(setPrice)
import React, { Component } from 'react'
export default class goods extends Component {
constructor (props) {
super(props)
}
render() {
return (
<>
<p>价格{this.props.price}</p>
</>
)
}
}
高阶组件-增加数量与总价(withNum)
这个组件在购物车、结算中需要,但是在商品列表中他是不需要的
import React, { Component } from 'react'
import memoizeOne from "memoize-one";
export default function HeightOriderNum (Comp) {
return class extends Component{
createSumPrice = memoizeOne((num,price) => {
return num*price
})
render () {
let sumPrice = this.createSumPrice(this.props.num,this.props.price)
return (
<>
<Comp {...this.props}></Comp>
<hr></hr>
<p>增强的数量和计算属性</p>
<p>数量{this.props.num}</p>
<p>总价{sumPrice}</p>
</>
)
}
}
}
高阶组件-增加数量(whiteBtn)
这个组件在购物车中需要,但是在商品列表、结算中他是不需要的
import React, { Component } from 'react'
import memoizeOne from "memoize-one";
export default function HeightOriderNum (Comp) {
return class extends Component{
createSumPrice = memoizeOne((num,price) => {
return num*price
})
render () {
let sumPrice = this.createSumPrice(this.props.num,this.props.price)
return (
<>
<Comp {...this.props}></Comp>
<hr></hr>
<p>增强的数量和计算属性</p>
<p>数量{this.props.num}</p>
<p>总价{sumPrice}</p>
</>
)
}
}
}
高阶组件-切换商品规格(withPrice)
因为没有商品规格用修改价格代替,这个在详情页中需要
import React, { Component , createRef} from 'react'
export default function HeightOriderBtn (Comp) {
return class extends Component{
state = {
price:this.props.price,
}
priceRef = createRef()
changePrice= (e) => {
this.setState({
price:this.priceRef.current.value
},() => {
this.priceRef.current.value=""
})
}
render () {
return (
<>
<Comp {...this.props} price={this.state.price}></Comp>
<hr></hr>
<p>增强的修改框</p>
<input ref={this.priceRef} defaultValue={this.state.price}></input>
<button onClick={this.changePrice}>修改价格</button>
</>
)
}
}
}
入口文件,进行高阶组件的组装
import setPrice from "./setPrice"; //引入基础的组件
import withNum from "./withNum"; //引入高阶组件
import withBtn from "./whiteBtn";
import withPrice from "./withPrice";
export default withPrice(withBtn(withNum(setPrice))) //通过层层的组件传入,获取最外层的高阶组件
使用这个高阶组件
<SetSumprice price={this.state.price} num = {this.state.num}></SetSumprice>
注意点
高阶组件除了自己特有功能的的state之外,其他的都应该保持props的设置,最好是无状态组件,才能更好的复用
高阶组件的状态最好还是存在redux这种全局状态中,让高阶组件保持无状态,这样才能够保持组件最好的复用性
props透传
高阶组件的层层状态要靠props来进行传输,将父组件的props透传到他的子组件,如果是有状态组件要将状态也传到子组件
<Comp {...this.props} {...this.state}></Comp> //组件的props进行透传