目录
1. 组件复用的说明
问题 1:如果两个组件中的部分功能相似或相同,但 UI 结构不同,该如何优化相似的功能?复用
问题 2:复用什么?1. state 状态 2. 操作 state 状态的方法。也就是:组件状态逻辑复用
在 Hooks 之前,组件的状态逻辑复用经历了:mixins(混入)、HOCs(高阶组件)、render-props 等模式
注意:这几种方式不是新的 API,而是利用 React 自身特点的编码技巧,演化而成的固定模式(写法)
通过一个鼠标位置的案例,来演示组件的状态逻辑复用。
2. mixins 混入(已废弃)
存在的问题:
-
Mixins 引入了隐式依赖关系,组件中的方法和数据的来源不明确,不利于维护
-
Mixins 导致名称冲突
3. 高阶组件
概述
高阶组件(HOC,High-Order Component)作用:通过增强组件的能力,来实现组件状态逻辑复用
采用 包装(装饰)模式 ,比如,
-
手机:获取保护功能
-
手机壳 :提供保护功能
高阶组件就相当于手机壳,通过包装组件,增强组件功能
基本使用
高阶组件是一个函数,接收要包装的组件,返回增强后的组件
高阶组件的命名约定以 with
开头,比如:withMouse、withRouter 等
原理:高阶组件内部创建一个类组件,在这个类组件中提供复用的状态逻辑代码,通过 prop 将复用的状态传递给被包装组件
// 高阶组件内部创建的类组件:
const withMouse = (BaseComponent) => {
class Wrapper extends React.Component {
state = {
x: 0,
y: 0,
};
render() {
// const { x, y } = this.state
return <BaseComponent x={x} y={y} {...wrapper组件状态数据} />;
}
}
return Wrapper;
};
// 参数:需要增强的组件
// 返回值:增强后的组件
const HOCComponent = withMouse(被包装的组件);
示例:
假设 withMouse 高阶组件,可以拿到鼠标位置状态,而 Cat 组件需要使用鼠标位置状态,就可以通过高阶组件来复用鼠标位置相关的状态逻辑代码了:
// withMouse 高阶组件:提供鼠标位置相关的状态逻辑
const CatWithMouse = withMouse(Cat);
// 复用1:
// 使用高阶组件包装后,组件内部就可以通过 props 来获取鼠标位置
const Cat = (props) => {
// props => { x: 1, y: 1 }
return (
<img
src={catImg}
style={
{
position: 'absolute',
top: props.y,
left: props.x,
}}
alt=""
/>
);
};
// 渲染时,要渲染增强后返回的组件
<CatWithMouse />;
// 复用2:
// 使用高阶组件包装后,组件内部就可以通过 props 来获取鼠标位置
const PositionWithMouse = withMouse(Position);
const Position = ({ x, y }) => {
return (
<div>
鼠标当前位置:(x: {x}, y: {y})
</div>