forked from kay-is/react-from-zero
-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy path12-component-refactor.html
136 lines (113 loc) · 3.44 KB
/
12-component-refactor.html
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
<!doctype html>
<title>12 Component Refactor - React From Zero</title>
<script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.4.0-alpha.0911da3/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/create-react-class@15.6.3/create-react-class.js"></script>
<script src="https://cdn.bootcss.com/prop-types/15.6.1/prop-types.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/7.0.0-beta.3/babel.min.js"></script>
<div id="app"></div>
<script type="text/babel">
// 重构是另一件`React`很好的事情
// 首先,我们将讨论如何将一个组件重构为另一个组件,
// 如果好运的话,您可以更改组件的实现,而无需在 呼叫站点 更改任何内容
// 我们从一个以某种方式 渲染 rooms 记录 的组件开始
function ViewBefore(props) {
return (
<table>
<thead>
<tr>
<th>Room</th>
<th>People</th>
</tr>
</thead>
<tbody>
{props.rooms.map(function(room, k) {
return <tr key={k}>
<td>{room.name}</td>
<td>{room.people}</td>
</tr>
})}
</tbody>
</table>
)
}
// 该组件有一个简单的`props`-接口
ViewBefore.propTypes = {
rooms: PropTypes.array.isRequired,
}
// 现在我们用更复杂的东西来实现
function ViewAfter(props) {
return (
<div>
{props.rooms.map(function(room, k) {
var barStyle = {
display: "inline-block",
background: "lightgrey",
width: room.people * 25,
}
return <div key={k}>
{room.people > 0
? <span style={barStyle}>{room.people} People</span>
: <span>0 People</span>
}
<span> in {room.name}</span>
</div>
})}
</div>
)
}
// 我们保持`props`- 接口相同
ViewAfter.propTypes = {
rooms: PropTypes.array.isRequired,
}
// 我们也可以用 更动态的东西 实现
var ViewDynamic = createReactClass({
// 我们仍然保持着`props`- 接口相同
propTypes: {
rooms: PropTypes.array.isRequired,
},
getInitialState: function() {
return {currentRoom: 0}
},
componentDidMount() {
var component = this
var props = this.props
this.interval = setInterval(function() {
var currentRoom = component.state.currentRoom < props.rooms.length - 1
? component.state.currentRoom + 1
: 0
component.setState({currentRoom: currentRoom})
}, 1000)
},
componentWillUnmount() {
clearInterval(this.interval)
},
render: function() {
var room = this.props.rooms[this.state.currentRoom]
return (
<span style={{color: this.state.color}}>
Room <b>{room.name}</b> has <b>{room.people}</b> People.
</span>
)
},
})
// 一些数据
var rooms = [
{name:"Office", people: 10},
{name:"Kitchen", people: 15},
{name:"Floor", people: 3},
{name:"Bathroom", people: 0},
]
// 正如我们所看到的,组件的使用方式完全相同
// 如果我们将 ViewAfter的实现 复制到 ViewBefore 中,所有内容都可以继续工作
var reactElement =
<div style={{margin: "auto", width: 500}}>
<h3>Before the refactor</h3>
<ViewBefore rooms={rooms}/>
<h3>After the refactor</h3>
<ViewAfter rooms={rooms}/>
<h3>Dynamic refactor</h3>
<ViewDynamic rooms={rooms}/>
</div>
ReactDOM.render(reactElement, document.getElementById("app"))
</script>