什么是HOC
HOC全称是高阶函数组件,其本质就是一个函数。调用这个函数需要传入原来的组件返回一个新的增强组件。例如Redux的connect
函数。
function withLocationQuery(Component){
const queryParams = parserSearch(location.search) || {};
return function LocationQueryComp(props){
return (
<Component {...queryParams} {...props} />
)
}
}
在👆🏻例子中withLocationQuery
就是一个HOC,他将queryParams注入到了Component的props内。
注意📢!!!
HOC用来增强props时不可以修改组件原有的逻辑。
HOC能做的功能很多强化props只是其中一项,比如渲染劫持,生命周期拦截等等,但是常用的还是增强props。
什么是Render Props
Render Props是另一种代码抽离方案,他的使用场景是:当两个组件实现功能基本一致,但是UI大不相同时就可以使用Render Props。
举个例子
当鼠标移动时ChildCom1
需要显示鼠标的位置,ChildCom2
需要显示一个跟随的小球。
function App() {
return (
<div style={{
display: 'flex',
justifyContent: 'space-between',
width: "850px"
}}>
<MouseMove>
{(props) => <ChildCom1 {...props} />}
</MouseMove>
<MouseMove>
{props => <ChildCom2 {...props} />}
</MouseMove>
</div>
);
}
function MouseMove(){
const [points, setPoints] = useState({
x: 0,
y: 0,
});
function handleMouseMove(e) {
setPoints({
x: e.clientX,
y: e.clientY,
});
}
return props.render ? props.render({ points, handleMouseMove }) : null;
}
function ChildCom1(props) {
return (
<div style={{
width: '400px',
height: '400px',
backgroundColor: 'red'
}} onMouseMove={props.handleMouseMove}>
<h1>移动鼠标!</h1>
<p>当前的鼠标位置是 ({props.points.x}, {props.points.y})</p>
</div>
);
}
function ChildCom2(props) {
return (
<div
style={{
width: "400px",
height: "400px",
backgroundColor: "grey",
position: "relative",
overflow: "hidden",
}}
onMouseMove={props.handleMouseMove}
>
<h1>移动鼠标!</h1>
{/* 这里减去 460 是因为要减去左边 div 的宽度 + 两个大 div 之间 50 的间距 */}
<div
style={{
width: "15px",
height: "15px",
borderRadius: "50%",
backgroundColor: "white",
position: "absolute",
left: props.points.x - 5 - 460,
top: props.points.y - 5 - 10,
}}
></div>
</div>
);
}
一般来讲,Render Props 应用于组件之间功能逻辑完全相同,仅仅是渲染的视图不同。这个时候我们可以通过 Render Props 来指定要渲染的视图是什么。
而 HOC 一般是抽离部分公共逻辑,也就是说组件之间有一部分逻辑相同,但是各自也有自己独有的逻辑,那么这个时候使用 HOC 比较合适,可以在原有的组件的基础上做一个增强处理。