0%

使用render-props模式和高阶组件实现组件复用

props-render模式

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import img from './logo512.png' //图片是不能从public文件夹里面导入的,只能从src里面导入
import PropoTypes from "prop-types"
//使用render-props和高阶组件实现组件的复用
//复用组件首先要获取组件的状态和操作组件的方法
//问题1:如何拿到该组件复用的state
//可以通过添加一个值为函数的props,通过函数参数来获取(需要组件内部实现)
//问题2:如何渲染任意的UI===》使用该函数的返回值作为要渲染的内容

class Mouse extends React.Component{
state = {
x: 0,
y: 0,
}

handleMouseMove=(e)=>{
this.setState({
x: e.clientX,
y: e.clientY
})
}

componentDidMount(){
window.addEventListener('mousemove',this.handleMouseMove)
}

componentWillUnmount(){
window.removeEventListener('mousemove',this.handleMouseMove)
}

render(){
return this.props.render(this.state)
}
}

Mouse.PropoTypes={
render: PropoTypes.func.isRequired
}

class App extends React.Component {
render(){
return(
<div>
<p>props模式</p>
{/* <Mouse/> */}
<Mouse render={(mouse)=>{ return(

<p>当前坐标为{mouse.x}:{mouse.y}</p>
)}

}/>
<Mouse render={(mouse)=>{
return <img src={img} alt="猫"
style={{position: "absolute",
top: mouse.y, left: mouse.x,
transform: 'translate(-50% ,-50%)',
width:"200px",
height:"200px"
}}/>
}} />
</div>
)
}
}

ReactDOM.render(
<App/>,
document.getElementById('root')
);

Mouse组件的render属性必须是一个函数,且可以用childre属性来代替,这样的话可以将函数直接作为Mouse组件的一个文本节点(文本节点拥有props.children,而不用作为Mouse的属性。

高阶组件

使用步骤:

1、创建一个函数,名称约定以with开头;

2、指定函数参数,参数应该以大写字母开头(作为要渲染的组件)

3、在函数内部创建一个类组件,提供复用的状态逻辑代码,并返回

4、在该组件中,渲染参数组件,同时将状态通过props传递给参数组件

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import img from './logo512.png'

function withMouse(WrappedComponent){
class Mouse extends React.Component{
state={
x: 0,
y: 0,
}

handleMouseMove=(e)=>{
this.setState({
x : e.clientX,
y : e.clientY
})
}

componentDidMount(){
window.addEventListener('mousemove', this.handleMouseMove)
}

componentWillMount(){
window.removeEventListener('mousemove', this.handleMouseMove)
}


render(){
return (
<WrappedComponent {...this.state} {...this.props}></WrappedComponent>
)
}
}

return Mouse;

}

const Position = props=>
<p>
鼠标当前的位置:x:{props.x} ,y:{props.y}
</p>

const catPosition = props=>(
<img src = {img} alt="猫" style={{
position: "absolute",
top: props.y,
left: props.x,
width: "100px",
height: "100px",
transform: 'translate(-50% ,-50%)',

}} />
)



let Mouseposition = withMouse(Position);
let CatPosition = withMouse(catPosition)

class App extends React.Component {
render(){
return(
<div>
<p>高阶组件</p>
<Mouseposition />
<CatPosition></CatPosition>
</div>
)
}
}

ReactDOM.render(
<App/>,
document.getElementById('root')
);