HOC
- 高阶组件实际上就是一个函数;
- 这个函数接收一个组件;
- 返回的也是一个组件;
- 于是我们就可以在这个高阶组件里面定义一些公共逻辑。
import React, { useState } from "react";
const withMouse = (Component: any) => {
const withMouseComponent = (props: any) => {
const [position, setPosition] = useState({ x: 0, y: 0 })
const handleMouseMove = (e: any) => {
setPosition({
x: e.clientX,
y: e.clientX,
})
}
return (
<div style={{ height: '500px' }} onMouseMove={handleMouseMove}>
<Component {...props} position={position}/>
</div>
)
}
return withMouseComponent
}
const Learn = (props: any) => {
const { a } = props;
const { x, y } = props.position;
return (
<>
<h1>this mouse position is ({ x }, { y })</h1>
<p>{a}</p>
</>
)
}
export default withMouse(Learn);
RenderProps
- 实际上就是一个组件;
- 这个组件接收一个返回 React 元素的函数组件作为属性(一般命名为 render );
- 我们可以在这个组件内部定义一些公共逻辑;
- 于是我们可以把这个组件里定义的 state 传递给这个 render 函数;
- 然后用这个 render 函数实现 UI;
- 于是实现了逻辑和 UI 的分离。
import React, { useState } from "react";
const Mouse = (props: any) => {
const { render } = props; // 拿到 render 函数,实际上是一个函数组件
// 可以在这里定义公共逻辑
const [position, setPosition] = useState({ x: 0, y: 0 })
const handleMouseMove = (e: any) => {
setPosition({
x: e.clientX,
y: e.clientX,
})
}
return (
<div style={{ height: '500px' }} onMouseMove={handleMouseMove}>
{render(position)}
</div>
)
}
const Learn = (props: any) => (
<>
<p>{props.a}</p>
<Mouse
render={
// 这里实际上就是一个函数组件,它可以拿到 Mouse 组件内部的数据实现透传
(position: any) => <p>this mouse position is ({ position.x }, { position.y })</p>
}
/>
</>
)
export default Learn;
HOC 和 Render Props 比较
- HOC 模式更加简单,但是会增加组件层级;
- 代码更加简洁,但学习成本高;
- Reader Props 在处理透传上更加方便;