forked from kay-is/react-from-zero
-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy path13-element-refactor.html
More file actions
103 lines (71 loc) · 3.18 KB
/
13-element-refactor.html
File metadata and controls
103 lines (71 loc) · 3.18 KB
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
<!doctype html>
<title>13 Refatoração de Elementos - 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/@babel/standalone/babel.min.js"></script>
<div id="app"></div>
<script type="text/babel">
// Refatorar um elemento é um pouco mais complexo
// Primeiro, a capitalização do JSX determina se uma tag é um elemento ou componente
// lowercase é elemento
// uppercase é componente
var element = <div/>
// se torna
element = React.createElement("div", null)
try {
var component = <Div/>
// se torna
component = React.createElement(Div, null)
} catch(e) {}
// Segundo, o React converte todos os eventos que os elementos engatilham em
// eventos sintéticos. Isso normalmente não é um problema, por serem eventos simples.
// Mas você não pode engatilhar seus próprios.
// Então mesmo que seu componente <Input> aceite um callback onClick como propriedade
// Você não pode chama-la com o mesmo evento que um elemento <input> faria
// Uma abordagem poderia ser:
// Simplismente implementamos nossa própria chamada onChange
// Aqui criamos um input numérico que só chama onChange com inputs numéricos
// (não-números chamam uma mudança vazia)
var NumberInput = createReactClass({
getInitialState: function() {
return {value: ""}
},
handleInput: function(e) {
// podemos tentar modifcar o evento para inserir nossos dados
// mas isso pode bagunçar as coisas
// ao invés disso prevenimos que esse evento faça outras ações
e.preventDefault()
var newNumber = e.target.value
// filtramos as mudanças vazias
if (newNumber.length < 1 || newNumber === this.state.value) return
this.setState({value: newNumber})
// e finalmente extraimos nosso dado e passamos para onChange
this.props.onChange(newNumber)
},
render: function () {
return <input type="number" value={this.state.value} onChange={this.handleInput}/>
},
})
function logChange(v) {
console.log(v)
}
// Aqui vemos que o novo NumberInput tem uma interface diferente
// sua propriedade onChange implica que eventos serão recebidos, mas não é
// o caso. Também, mesmo se quisessemos chamar como o input original
// precisariamos usar uppercase, e não ganhariamos nada
var reactElement = <div style={{width: 300, margin: "auto"}}>
<h2>Logging number inputs</h2>
<h2>Before Refactor</h2>
<input type="number" onChange={function(e) { logChange(e.target.value) }}/>
<h2>After Refactor</h2>
<NumberInput onChange={logChange}/>
</div>
ReactDOM.render(reactElement, document.getElementById("app"))
// Outras abordagens incluem não usar "padrões" para nomes de propriedades em primeiro lugar
// onUpdate ao invés de onChange
// Mas pode acontecer que um componente use onMouseDown para algo interno
// e chame um onChange, o que poderia causar confusão
// Comumente componentes entregam interações mais ricas que elementos em primeiro lugar
// para que seus metodos propriedades possam refletir os com o mesmo nome
</script>