forked from vasanthk/react-bits
-
Notifications
You must be signed in to change notification settings - Fork 0
/
17.controlled-uncontrolled-input.jsx
137 lines (115 loc) · 4.66 KB
/
17.controlled-uncontrolled-input.jsx
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
/**
* Controlled - Uncontrolled Components
* Gist: https://gist.github.com/vasanthk/a6bf35857749b09275a339f6fd9469bb
* In depth: https://goshakkk.name/controlled-vs-uncontrolled-inputs-react/
*
* @Reference:
* https://www.sitepoint.com/video-controlled-vs-uncontrolled-components-in-react/
* https://facebook.github.io/react/docs/uncontrolled-components.html
*/
// It’s hard to talk about controlled inputs in the abstract. Let’s start with an uncontrolled (normal) input and go from there.
// So, a normal HTML input field effectively stores its own value at all times, and you can get the element and ask for its value.
// this is what we refer to as an "uncontrolled" input
// What makes an element “controlled”?
// There are other form elements, of course. You have checkboxes and radios and selects and textareas.
// A form element becomes “controlled” if you set its value via a prop. That’s all.
let simpleInput = '<input type="text" />';
// When you fiddle with this input in the browser, you see your changes. This is normal.
// A controlled input disallows the DOM mutations that make this possible.
// You set the value of the input in component-land and it doesn’t change in DOM-land.
let simpleInput = '<input type="text" value="This won\'t change. Try it." />';
// Obviously static inputs aren’t very useful to your users. So, we derive a value from state.
class UncontrolledNameInput extends React.Component {
constructor() {
super();
this.state = {name: ""}
}
render() {
return <input type="text" value={this.state.name} />
}
};
// Then, changing the input is a matter of changing component state.
class ControlledNameInput extends Component {
constructor() {
super();
this.state = {name: ""}
}
render() {
return (
<input
value={this.state.name}
onChange={e => this.setState({name: e.target.value})}
/>
);
}
}
// This is a controlled input. It only updates the DOM when state has changed in our component. This is invaluable when creating consistent UIs.
// If you’re using stateless functions for form elements, read about using state hoisting to move new state up the component tree.
// Note:
// In React, you can still create "uncontrolled" inputs: Using 'refs'
// The ref attribute takes a callback function, and the callback will be executed immediately after the component is mounted or unmounted.
// When the ref attribute is used on an HTML element, the ref callback receives the underlying DOM element as its argument.
// More on refs: https://facebook.github.io/react/docs/refs-and-the-dom.html
class MyComponent extends React.Component {
onClick() {
const input = this.refs.myInput;
const value = input.value;
// do something with the value
}
render() {
return <input type="text" ref="myInput" />
}
}
// We can make this even simpler by using array fns in ref
class NameForm extends React.Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(event) {
alert('A name was submitted: ' + this.input.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" ref={(input) => this.input = input} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
// Since an uncontrolled component keeps the source of truth in the DOM, it is sometimes easier to integrate React and non-React code when using uncontrolled components.
// It can also be slightly less code if you want to be quick and dirty. Otherwise, you should usually use controlled components.
// DEFAULT VALUES
// In the React rendering lifecycle, the value attribute on form elements will override the value in the DOM.
// With an uncontrolled component, you often want React to specify the initial value, but leave subsequent updates uncontrolled.
// To handle this case, you can specify a defaultValue attribute instead of value.
class NameForm extends React.Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(event) {
alert('A name was submitted: ' + this.input.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input
defaultValue="Bob"
type="text"
ref={(input) => this.input = input}/>
</label>
<input type="submit" value="Submit"/>
</form>
);
}
}
// Likewise, <input type="checkbox"> and <input type="radio"> support defaultChecked, and <select> supports defaultValue.