React 高级使用 高阶组件
- mixin, 已被 React 弃用
- 高阶组件 HOC
- Render Props
# HOC
类似工厂模式 装饰器之类的
//高阶组件不是一种功能,而是一种模式
const HOCFactory = (Component) => {
class HOC extends React.Component {
// 在此定义多个组件的公共逻辑
render(){
return <Component {...this.props}/>//返回拼装的结果
}
return HOC
}
const EnhancedComponent1 = HOCFactory(wrappedComponent1)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
示例:
import React from 'react'
// 高阶组件
const withMouse = (Component) => {
class withMouseComponent extends React.Component {
constructor(props) {
super(props)
this.state = { x: 0, y: 0 }
}
handleMouseMove = (event) => {
this.setState({
x: event.clientX,
y: event.clientY
})
}
render() {
return (
<div style={{ height: '500px' }} onMouseMove={this.handleMouseMove}>
{/* 1. 透传所有 props 2. 增加 mouse 属性 */}
<Component {...this.props} mouse={this.state}/>
</div>
)
}
}
return withMouseComponent
}
const App = (props) => {
const a = props.a
const { x, y } = props.mouse // 接收 mouse 属性
return (
<div style={{ height: '500px' }}>
<h1>The mouse position is ({x}, {y})</h1>
<p>{a}</p>
</div>
)
}
export default withMouse(App) // 返回高阶函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# redux connect 高阶组件
import { connect } from 'react-redux'
// connect 是高阶组件
const VisibleTodoList = connect(
mapStateToProps,
mapDispatchToProps
)(TodoList)
export default VisibleTodoList
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
connect 源码
# Render Props
Render Props 的核心思想 通过一个函数将 class 组件的 state 作为 props 传递给纯函数组件
class Factory extends React.Component {
constructor() {
this.state ={
/* state 即多个组件的公共逻辑的数据*/
}
}
/* 修改 state */
render(){
return <div-{this. props. render(this.state)J</div>
}
}
const App = () =>(
<Factory render={
/* render 是一个函数组件*/
(props) => <p>{props.a} {props.b} ...</p>
}>
</Factory>
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 示例
import React from 'react'
import PropTypes from 'prop-types'
class Mouse extends React.Component {
constructor(props) {
super(props)
this.state = { x: 0, y: 0 }
}
handleMouseMove = (event) => {
this.setState({
x: event.clientX,
y: event.clientY
})
}
render() {
return (
<div style={{ height: '500px' }} onMouseMove={this.handleMouseMove}>
{/* 将当前 state 作为 props ,传递给 render (render 是一个函数组件) */}
{this.props.render(this.state)}
</div>
)
}
}
Mouse.propTypes = {
render: PropTypes.func.isRequired // 必须接收一个 render 属性,而且是函数
}
const App = (props) => (
<div style={{ height: '500px' }}>
<p>{props.a}</p>
<Mouse render={
/* render 是一个函数组件 */
({ x, y }) => <h1>The mouse position is ({x}, {y})</h1>
}/>
</div>
)
/**
* 即,定义了 Mouse 组件,只有获取 x y 的能力。
* 至于 Mouse 组件如何渲染,App 说了算,通过 render prop 的方式告诉 Mouse 。
*/
export default App
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# HOC VS Render Props
- HOC:模式简单,但会增加组件层级
- Render Props:代码简洁,学习成本较高
上次更新: 2022/08/14, 18:25:44