什么是高阶组件
高阶组件是包装了另一个React组件的React组件
怎么理解高阶组件
可以简单将其理解成 “类工厂”
将一些可复用的逻辑写在高阶组件中,把一个普通组件传入高阶组件,通过返回值的形式,将处理好的组件return出来
即:高阶组件为一个函数,接收一个组件作为参数,并且返回值为一个新组件
1`function HOC (OneComponent) {
2 return class NewComponent extends Component {
3 render() {
4 return <OneComponent {...this.props} />
5 }
6 }
7}`
高阶组件的目的
将可复用的逻辑进行组件化封装,更好的将逻辑与 UI 分离
让我们在增强原有组件的功能的同时,不破坏组件原有的特性
1`// 通过高阶组件给基础组件添加新属性
2function HOC (OneComponent) {
3 return class NewComponent extends Component {
4 const newProps = {
5 id: 1,
6 name: '张三'
7 }
8 render() {
9 return <OneComponent {...this.props} {...newProps} />
10 }
11 }
12}
13// 可以在 OneComponent 中,通过this.props.id/this.props.name去获取新添加的属性`
1`// 通过高阶组件给基础组件添加新方法
2function HOC (OneComponent) {
3 return class NewComponent extends Component {
4 constructor(props) {
5 super(props)
6 this.state = {
7 count: 0 // 定义一个私有属性
8 }
9 }
10 const add = () => {
11 this.setState({
12 count: this.state.count + 1
13 })
14 }
15 const newProps = {
16 num: this.state.count,
17 add: () => this.add()
18 }
19 render() {
20 return <OneComponent {...this.props} {...newProps}/>
21 }
22 }
23}
24// 通过HOC这个高阶组件,给基础组件添加了一个'num'属性和'add'这个方法`
demo
场景:
简单计数器:在页面记录总数,给出两个按钮,一个控制总数加,一个控制总数减
方案一:
通过高阶组件的形式实现
1`// 主函数
2// 这里直接解构props
3const Main = ({count, add, minus}) => {
4 return (
5 <div>
6 <p>当前总数{count}</p>
7 <button onClick={() => add()}>加</button>
8 <button onClick={() => minus()}>减</button>
9 </div>
10 )
11}
12
13export default HOC(Main)`
1`// 高阶组件函数
2const HOC = (OneComponent) => {
3 return class NewComponent extends Component {
4 constructor(props) {
5 super(props)
6 this.state = {
7 count: 0 // 总数
8 }
9
10 // 点击事件:总数加一
11 const add = () => {
12 this.setState({
13 count: this.state.count + 1
14 })
15 }
16
17 // 点击事件:总数减一
18 const minus = () => {
19 this.setState({
20 count: this.state.count - 1
21 })
22 }
23
24 render() {
25 // 通过props的方式传出
26 return <OneComponent
27 {...this.props}
28 count={this.state.count}
29 add={() => this.add()}
30 minus={() => this.minus()}
31 />
32 }
33 }
34 }
35}`
优点:
1`* 更方便的实现相同逻辑的复用,可以直接给其他组件反复使用
2 * 通过高阶组件的state,驱动无状态组件的数据刷新,实现逻辑和UI分离,代码清晰`
缺点:
1`* 对属性名称限制大,若同样功能,属性名称不一致,就导致高阶组件失效`
方案二:
通过自定义Hooks的方式实现
1`// 主函数
2const Count = () => {
3 const [count, add, minus] = useCount()
4 return (
5 <div>
6 <p>当前总数{count}</p>
7 <button onClick={() => add()}>加</button>
8 <button onClick={() => minus()}>减</button>
9 </div>
10 )
11}`
1`// 自定义hook
2const useCount = () => {
3 // 初始化总数值
4 const [count, setCount] = useState(0)
5 // 点击事件:总数加一
6 const add = () => {
7 setCount(count => count + 1)
8 }
9 // 点击事件:总数减一
10 const minus = () => {
11 setCount(count => count - 1)
12 }
13 // 将属性值和方法导出
14 return [
15 count,
16 add,
17 minus
18 ]
19}`
优点:
- 代码量减少,逻辑相对清晰
- 结构相对于高阶组件更加简单明了
- 不受属性名称限制
个人总结:
高阶组件是在使用class组件时,state被定义在了内部,导致逻辑上的复用困难,才出现的一种设计模式。
但是在新版的React中,整个React社区都在推崇函数式的编程方式,所以Hooks的学习就变得重要起来。一些简单的逻辑复用完全可以使用Hooks去实现,避免使用高阶组件使组件变得极其复杂。
个人笔记记录 2021 ~ 2025