Forms Back
Form components such as <input>
, <textarea>
and <option>
differ from other native components because of their mutation via use interactions.
Form components support a few props that can be changed via user interacitons:
value
:<input>
or<textarea>
components.checked
:<input>
components of typecheckbox
orradio
.selected
:<option>
components.
Form components allow listening for changes by setting a callback to the onChange
prop.
Note:
For
<input>
and<textarea>
,onChange
supersedes(替代) the DOM's built-inoninput
event handler.
A Controlled <input>
has a value
prop. Rendering a controlled <input>
will reflect the value of the value
prop.
var InputComponent = React.creteClass({
render: function () {
return <input type="text" value="Hello!" />;
}
});
User input will have no effect on the rendered element because React has declared the value to be Hello!
. To update the value in response to user input, you could use the onChange
event:
var InputComponent = React.creteClass({
getInitialState: function () {
return { value: 'Hello!' };
},
handleChanged: function(event) {
this.setState({ value: event.target.value });
},
render: function () {
return (
<input type="text" value={this.state.value} onChange={this.handleChanged} />
);
}
});
Notice that: A Controlled component does not maintain its own internal state; the component renders purely based on props.
Be aware that, in an attempt to normalize change handling for checkbox and radio inputs, React uses a click
event in place of a change
event. That's because when calling preventDefault
in a change
handler. preventDefault
stops the browser from visually updating the input, even if checked
gets toggled. (Solved by removing the call to preventDefault
, or putting the toggle of checked
in a setTimeout
.
An <input>
without a value
property is an uncontrolled component:
var InputComponent = React.creteClass({
render: function () {
return <input type="text" />;
}
});
If you want to listen to updates to the value, you can also use onChange
like handling controlled components.
Notiec that: An uncontrolled component maintains its own internal state.
If you want to initialize the component with a non-empty value, you can supply a defaultValue
prop.
var InputComponent = React.creteClass({
render: function () {
return <input type="text" defaultValue="Hello!" />;
}
});
Likewise, <input type="checkbox">
and <input type="radio">
support defaultChecked
, and <select>
supports defaultValue
.
Note:
The
defaultValue
anddefaultChecked
props are only used during initial render. If you need to update the value in a subsequent render, you will need to use a controlled component.
In HTML, we suppose that we have a <input>
tag:
<input type="text" name="title" value="Untitled" />
When the user updates the input, the node's vaule
property will change. However, node.getAtribute('value')
should still return the value used at initialization time, Untitled
.
var InputComponent = React.creteClass({
render: function () {
return <input type="text" name="title" value="Untitled" />;
}
});
However, in React, the value should always be Untitled
, no matter what the user has changed. Therefore, the state of the view has kept in consistent.
In HTML, the value of <textarea>
is usually set using its children:
<!-- antipattern: DO NOT DO THIS! -->
<textarea name="description">This is the description.</textarea>
For HTML, this easily allows developers to supply multiline values. However, since React is JavaScript, we do not have string limitations and can use \n
if we want newlines. In a world where we have value
and defaultValue
, it is ambiguous what role children play. For this reason, you should not use children when setting <textarea>
values:
<textarea name="description" value="This is a description." />
In HTML, The selected <option>
in an HTML <select>
is normally specified through that option's selected
attribute.
However in React, in order to make components easier to manipulate, the following format is adopted instead:
<select value="B">
<option value="A">Apple</option>
<option value="B">Banana</option>
<option value="C">Cranberry</option>
</select>
To make an uncontrolled component, defaultValue
is used instead.
Note:
You can pass an array into the
value
attribute, allowing you toselect
multiple options in a select tag:<select multiple={true} value={['B', 'C']}>
.
If you need to imperatively perform an operation, you have to obtain a reference to the DOM node. For instance, if you want to imperatively submit a form, one approach would be to attach a ref
to the form
element and manually call form.submit()
.