高阶函数:接受函数作为参数的函数,其实map函数就是一个高阶函数
高阶组件:不是React提供的某种API,而是使用React的一种模式,类似于高阶函数,即指接受React组件作为参数,输出一个新的组件的函数。在这个函数中,我们可以修饰组件的props与state,所以在一些特定情况下高阶组件可以让我们的代码看起来更优美。
注:返回的新组件拥有了输入组件所不具备的功能。这里提到的组件
并不是组件实例,而是组件类,也可以是一个无状态组件的函数。
作用:
- 更具有复用性:有时候很多React组件都需要公用同样一个逻辑,比如React-Redux中容器组件的部分,没有必要让每个组件都实现一遍shouldComponentUpdate这些生命周期函数,把这部分逻辑提取出来,利用高阶组件的方式应用出去,就可以减少很多组件的重复代码。
- 修改现有React组件的行为:有些现成的React组件并不是开发者自己开发的,来自于第三方,或者即便是我们自己开发的,但是我们不想去触碰这些组件的内部逻辑,这时候可以用高阶组件。通过一个独立于原有组件的函数,可以产生新的组件,对原有组件没有任何侵害。
目前,高阶组件的实现方式主要有两种:
- 代理方式的高阶组件:高阶组件通过被包裹的React组件来操作props
- 高阶组件中可以修饰props于state的,在高阶组价中定义state,作为props传给参数组件(InnerComponent)
- 高阶组件也可以传方法到参数组件(InnerComponent)中
- 高阶组件的生命周期不会影响传入的组件
- 并不是高阶组件的所有生命周期都会先执行
- 由同一个高阶组件生成的新的组件间其实是相互不会影响的
- 继承方式的高阶组件:高阶组件继承于被包裹的React组件
- 操纵props
- 操纵生命周期
代理方式实例
const HOC = (InnerComponent) => class extends React.Component{
static defaultProps = {
n:'HOC'
}
constructor(){
super();
this.state = {
count:0
}
}
componentWillMount(){
console.log('HOC will mount')
}
componentDidMount(){
console.log('HOC did mount')
}
update = () =>{
const {count} = this.state
this.setState({
count:count+1
})
}
render(){
const newProps = this.state;
return(
<InnerComponent
{...this.props}
{...newProps} //传state
update = {this.update} //传方法
/>
)
}
}
//无状态组件
const Button = HOC((props) => <button onClick={props.update}>{props.children}-{props.count}</button>) //无状态组件
//Button中改变count,不会影响Label组件中的count
class Label extends React.Component{//传统组件
static defaultProps = {
n:'C'
}
componentWillMount(){
console.log('C will mount')
}
componentDidMount(){
console.log('C did mount')
}
render(){
return(
<label>{this.props.children}-{this.props.count}</label>
)
}
}
const LabelHoc = HOC(Label)
class App extends React.Component{//根组件
render(){
return(
<div>
//随着点击渲染出label-0、1、2.....
<Button>button</Button>
<br/>
//渲染出:label-0
<LabelHoc>label</LabelHoc>
</div>
)
}
}
继承方式实例
const HOC = (WrappedComponent) =>
class NewComp extends WrappedComponent {
componentWillMount() {
console.log('我是继承高阶组件中的生命周期')
}
render() {
// 获取继承而来的传入组件的元素内容
const element = super.render()
const newStyle = {
color:element.type === 'div' ? 'red' : 'yellow'
}
const newProps = {...this.props, style: newStyle}
// React.cloneElement方法生成新的React对象
return React.cloneElement(element, newProps, element.props.children)
}
}
export default HOC
普通组件传入高级组件
@HOC
class A extends Component {
componentWillMount() {
console.log('我是普通组件中生命周期')
}
render() {
return (
<div>我是普通组件</div>
)
}
}
export default A
最终效果:div是红色 ———— 这是操纵props实例
输出:我是继承高阶组件中的生命周期(A中生命周期内容不见了,被继承高阶组件给劫持了) ————
这就是继承高阶组件操纵生命周期