Componentes no controlados
En la mayoría de los casos, te recomendamos usar Componentes controlados para implementar formularios. En un componente controlado, los datos del formulario son manejados por un componente React. La alternativa son los componentes no controlados, donde los datos del formulario son manejados por el propio DOM.
Para escribir un componente no controlado, en lugar de escribir un controlador de eventos para cada actualización de estado, puedes usar una referencia para que obtengas los valores del formulario desde el DOM.
Por ejemplo, este código acepta un solo nombre en un componente no controlado:
class NameForm extends React.Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
this.input = React.createRef(); }
handleSubmit(event) {
alert('A name was submitted: ' + this.input.current.value); event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" ref={this.input} /> </label>
<input type="submit" value="Submit" />
</form>
);
}
}
Ya que un componente es la fuente de la verdad en el DOM, a veces es más fácil integrar el código React y el código no React cuando usas componentes no controlados. También puede haber menos código si optas por una solución rápida y sin muchos miramientos. De lo contrario, deberías por lo general utilizar componentes controlados.
Si aún no tienes claro qué tipo de componente debes usar para una situación en particular, puedes encontrar este artículo sobre entradas controladas y no controladas que puede ser útil.
Valores predeterminados
En el ciclo de vida de renderizado de React, el atributo value
en los elementos de formulario reemplazará el valor en el DOM. Con un componente no controlado, a menudo lo quieres es que React especifique el valor inicial, pero no controlar las actualizaciones posteriores. Para manejar este caso, puedes especificar un atributo defaultValue
en lugar de value
. Cambiar el valor del atributo defaultValue
después de que un componente ha sido montado no causará ninguna actualización del valor en el DOM.
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input
defaultValue="Bob" type="text"
ref={this.input} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
Del mismo modo, <input type="checkbox">
e <input type="radio">
admiten defaultChecked
, y <select>
y <textarea>
admiten defaultValue
.
La etiqueta de entrada de archivo
En HTML, un <input type="file">
permite al usuario elegir uno o más archivos del almacenamiento en sus dispositivos para cargarlos a un servidor o manipularlos mediante JavaScript a través de la API de archivos.
<input type="file" />
En React, un <input type="file" />
siempre es un componente no controlado porque su valor solo puede ser establecido por un usuario, y no mediante programación.
Debes utilizar la API File para interactuar con ellos. El siguiente ejemplo muestra cómo crear un referencia al nodo DOM para acceder a los archivos en un controlador de envío:
class FileInput extends React.Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
this.fileInput = React.createRef(); }
handleSubmit(event) {
event.preventDefault();
alert(
`Selected file - ${this.fileInput.current.files[0].name}` );
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Upload file:
<input type="file" ref={this.fileInput} /> </label>
<br />
<button type="submit">Submit</button>
</form>
);
}
}
ReactDOM.render(
<FileInput />,
document.getElementById('root')
);