forked from kay-is/react-from-zero
-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy path12-component-refactor.html
138 lines (115 loc) · 3.47 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
137
138
<!doctype html>
<title>12 Refatoração de Componentes - React do Zero</title>
<script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/[email protected]/create-react-class.js"></script>
<script src="https://unpkg.com/[email protected]/prop-types.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<div id="app"></div>
<script type="text/babel">
// Refatoração é outra coisa que é simples no React
// Primeiro falemos sobre refatorar um componente em outro
// se você tiver sorte, basta apenas mudar a implementação do componente
// sem precisar de mudar nada na local da chamada da função
// Comecemos com um componente que renderiza registros
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>
)
}
// O componente tem uma interface de propriedades simples
ViewBefore.propTypes = {
rooms: PropTypes.array.isRequired,
}
// Agora mudemos a implementação para algo mais complexo
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>
)
}
// Podemos manter a interface da mesma maneira
ViewAfter.propTypes = {
rooms: PropTypes.array.isRequired,
}
// Também podemos trocar por algo mais dinâmico
var ViewDynamic = createReactClass({
// Ainda assim mantemos a interface a mesma
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>
)
},
})
// Alguns dados
var rooms = [
{name:"Office", people: 10},
{name:"Kitchen", people: 15},
{name:"Floor", people: 3},
{name:"Bathroom", people: 0},
]
// Como podemos ver os componentes podem ser usados exatamente do mesmo modo
// Se copiarmos a implementação de ViewAfter em ViewBefore,
// tudo continua funcionando
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>