高阶组件如何进行多级包装
一般情况下,高阶组件接受一个组件作为参数,返回一个全新的组件,即:
//定义高阶组件
function Hoc(Element) {
/*这里返回的是函数型组件,也可以返回类组件 ,
**return class extends React.Component {} 或
**return class extends Element {}
**很明显第二种返回方式中,输入的组件参数Element必须为类组件才能被继承
*/
return props => {
return (
<div>
...
<Element></Element>
...
</div>
);
}
}
//使用高阶组件
@Hoc //ES7装饰器写法
class CElement extends React.Component {
render() {
return (
...
);
}
}
在这里,Hoc接受Element组件作为参数,对其进行包装扩展,然后返回一个新的组件。这个返回的组件是一个普通的组件,它已经无包装扩展能力。有些时候你可能希望这个返回的组件还具有包装扩展能力,那该怎么做呢?很简单,我们可以再包裹一层,让返回的组件也为高阶组件就行啦。就像下面这样:
//定义二级高阶组件
function TwoLevelHoc(ElementFirstLevel) {
return ElementSecondLevel => {
return props => { //这里返回的是函数型组件,也可以返回类组件
<div>
...
<ElementFirstLevel />
...
<ElementSecondLevel />
...
</div>
}
}
}
//使用二级高阶组件
function FirstElement(props) {
return (
...
);
}
@(TwoLevelHoc(FirstElement))
class SecondElement extends React.Component {
render() {
return (
...
);
}
}
export defualt SecondElement;
其他层级以此类推。
多级包装的渲染顺序
多级包装的渲染顺序是从父组件开始,然后进入高阶组件,然后根据传入组件的顺序逐层往里渲染,就像剥洋葱一样,从外往里。就拿上面的组件举例:
<FartherElement>
...
<SecondElement />
...
</FatherElement>
FartherElement开始
…
TwoLevelHoc —>FirstElement—>SecondElement
…
FartherElement结束
所以很明显,如果在组件中传入属性值,那么第一个先拿到的便是TwoLevelHoc,然后我们就可以根据需要,把属性值解构出来自身使用或者传递给FirstElement或SecondElement