Form components such as `<input>`, `<textarea>`, and `<option>` differ from other native components because they can be mutated via user interactions. These components provide interfaces that make it easier to manage forms in response to user interactions.
Two types of form components:
There are two types of form components:
* Controlled Components
* Uncontrolled Components
@ -20,15 +20,19 @@ You can jump directly to <a href="/react/docs/forms.html#examples">examples</a>.
A **controlled** form component provides a `value` prop. A **controlled** component does not maintain its own internal state; the component renders purely based on props.
```javascript
```javascript{5}
render() {
return <inputtype="text"value="Hello!"/>;
return (
<input
type="text"
value="Hello!" />
);
}
```
User input has no effect on the rendered element because React has declared the value to be "Hello!".
If you try to run this example, you will notice that the input doesn't change as you type. This is because the component has declared the input's `value` to always be `"Hello!"`.
To update the value in response to user input, you would use the `onChange` event to save the new value, then pass that to the `value` prop of the form:
To update the value in response to user input, you would use the `onChange` event to save the new value, then pass that to the `value` prop of the input:
```javascript{10,22,23}
class Form extends React.Component {
@ -54,34 +58,53 @@ class Form extends React.Component {
[Try it on CodePen.](https://codepen.io/ericnakagawa/pen/QKkJva?editors=0010)
[Try it on CodePen.](https://codepen.io/gaearon/pen/NRmBmq?editors=0010)
In this example, we are accepting the value provided by the user and updating the `value` prop of the `<input>` component. This pattern makes it easy to implement interfaces that respond to or validate user interactions. For example:
This would accept user input and truncate the value to the first 140 characters.
Controlled components also let us reset inputs to arbitrary values by setting the state:
```javascript{3}
handleClearClick() {
this.setState({
value: ''
});
}
```
### Potential Issues With Checkboxes and Radio Buttons
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. For the most part this behaves as expected, except when calling `preventDefault` in a `change` handler. `preventDefault` stops the browser from visually updating the input, even if `checked` gets toggled. This can be worked around either by removing the call to `preventDefault`, or putting the toggle of `checked` in a `setTimeout`.
Be aware that, in an attempt to normalize change handling for checkbox and radio inputs, React listens to a `click` browser event to implement the `onChange` event.
For the most part this behaves as expected, except when calling `preventDefault` in a `change` handler. `preventDefault` stops the browser from visually updating the input, even if `checked` gets toggled. This can be worked around either by removing the call to `preventDefault`, or putting the toggle of `checked` in a `setTimeout`.
## Uncontrolled Components
Form components that do not provide a `value` prop are *uncontrolled*.
Form components that do not provide a `value` prop are **uncontrolled**.
The example below renders an `<input>` control with an empty value. Any user input will be immediately reflected by the rendered element.
@ -95,7 +118,7 @@ An **uncontrolled** component manages its own state.
If you wanted to listen to updates to the value, you could use the `onChange` event just like you can with controlled components. However, you would _not_ pass the value you saved to the component.
```javascript{10,22}
```javascript{25}
class Form extends React.Component {
constructor(props) {
super(props);
@ -105,6 +128,8 @@ class Form extends React.Component {
}
handleChange(event) {
// Note: with uncontrolled inputs, you don't
// have to put the value in the state.
this.setState({value: event.target.value});
}
@ -115,21 +140,29 @@ class Form extends React.Component {
[Try it on CodePen.](https://codepen.io/ericnakagawa/pen/XjxyoL?editors=0010)
[Try it on CodePen.](https://codepen.io/gaearon/pen/pEBOJR?editors=0010)
###Default Values
While this example puts value in the state so we can later read it in `handleSubmit()`, uncontrolled form components don't require this. You may completely omit an `onChange` handler and instead read the input value using [DOM references](/react/docs/refs-and-the-dom.html), an advanced feature discussed later.
### Default Values
To initialize an uncontrolled component with a non-empty value, you can supply a `defaultValue` prop.
@ -190,7 +223,7 @@ Since this method describes the view at any point in time, the value of the text
In HTML, the value of `<textarea>` is usually set using its children:
```html
<!--antipattern: DO NOT DO THIS!-->
<!--Don't do this in React.-->
<textareaname="description">This is the description.</textarea>
```
@ -220,16 +253,16 @@ To make an uncontrolled component, `defaultValue` is used instead.
>
> You can pass an array into the `value` attribute, allowing you to select multiple options in a `select` tag: `<select multiple={true} value={['B', 'C']}>`.
### Imperative operations
### Imperative Operations
If you need to imperatively perform an operation, you have to obtain a [reference to the DOM node](/react/docs/more-about-refs.html#the-ref-callback-attribute).
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()`.
## Examples
### Basic Controlled Input
### Controlled Input
```javascript
```javascript{10,23,24}
class Form extends React.Component {
constructor(props) {
super(props);
@ -237,6 +270,7 @@ class Form extends React.Component {
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
@ -254,21 +288,25 @@ class Form extends React.Component {
> As of v0.14, returning `false` from an event handler will no longer stop event propagation. Instead, `e.stopPropagation()` or `e.preventDefault()` should be triggered manually, as appropriate.
### Event pooling
### Event Pooling
The `SyntheticEvent` is pooled. This means that the `SyntheticEvent` object will be reused and all properties will be nullified after the event callback has been invoked.