12 - Formularios: enlace de controles con el 'estado' de la componente

Cuando trabajamos con formulario HTML los controles almacenan el valor cargado. Con React es muy común enlazar cada control de formulario con atributos definidos en la propriedad 'state' de la componente.

Este enlace nos facilita implementar validaciones de ingreso de datos inmediatamente después que el operador los carga.

Problema

Confeccionar un formulario HTML que solicite la carga del nombre, edad y si tiene estudios o no una persona. Utilizar controles:

<input type="text"  />
<input type="number" />
<input type="checkbox" />

Almacenar en el 'estado' de la componente cada vez que ocurre un cambio en un control. Mostrar en todo momento que datos están almacenado en la propiedad 'state'

Crear con la aplicación create-react-app el proyecto011

La interfaz visual debe ser:

formularios react

App.js

import React, { Component } from 'react';
import './App.css';

class App extends Component {
  constructor(props) {
    super(props);
    this.state = ({
        nombre:'',
        edad:'',
        estudio: false
      })
    this.procesar = this.procesar.bind(this);
    this.cambioNombre = this.cambioNombre.bind(this);
    this.cambioEdad = this.cambioEdad.bind(this);    
    this.cambioEstudio = this.cambioEstudio.bind(this);
  }


  render() {
    return (
      <div>
        <form onSubmit={this.procesar}>
          <p>Ingrese nombre:<input type="text" value={this.state.nombre} onChange={this.cambioNombre} /></p>
          <p>Ingrese edad:<input type="number" value={this.state.edad} onChange={this.cambioEdad} /></p>
          <p>Estudios:<input type="checkbox" value={this.state.estudio} onChange={this.cambioEstudio} /></p>          
          <p><input type="submit" /></p>
        </form>
        <hr />
        <h3>Datos Ingresados</h3>
        <p>Nombre:{this.state.nombre}</p>
        <p>Edad:{this.state.edad}</p>
        <p>Estudios:{this.state.estudio ? 'con estudios':'sin estudios'}</p>        
      </div>
    );
  }

  procesar(e) {
    e.preventDefault();
    alert('Dato cargado '+this.state.nombre + ' ' + 
                         +this.state.edad + ' ' + 
                         +this.state.estudio);
  }

  cambioNombre(e) {
    this.setState( {
      nombre: e.target.value
    })
  }

  cambioEdad(e) {
    this.setState( {
      edad: e.target.value
    })
  }  

  cambioEstudio(e) {
    this.setState( {
      estudio: !this.state.estudio
    })
  }    
}

export default App;

En el constructor definimos tres propiedades en 'state' que las asociaremos con los tres controles de entrada de datos:

    this.state = ({
        nombre:'',
        edad:'',
        estudio: false
      })

Enlazamos los métodos que se ejecutarán cuando haya cambios en los controles de formulario:

    this.procesar = this.procesar.bind(this);
    this.cambioNombre = this.cambioNombre.bind(this);
    this.cambioEdad = this.cambioEdad.bind(this);    
    this.cambioEstudio = this.cambioEstudio.bind(this);

En el método render() mostramos los datos actuales del 'estado' de la componente asignando a la propiedad value el valor almacenado en 'state':

  render() {
    return (
      <div>
        <form onSubmit={this.procesar}>
          <p>Ingrese nombre:<input type="text" value={this.state.nombre} onChange={this.cambioNombre} /></p>
          <p>Ingrese edad:<input type="number" value={this.state.edad} onChange={this.cambioEdad} /></p>
          <p>Estudios:<input type="checkbox" value={this.state.estudio} onChange={this.cambioEstudio} /></p>          
          <p><input type="submit" /></p>
        </form>
        <hr />

También definimos para cada evento onChange un método que sincronizará el control con el 'estado'.

Mostramos en el mismo método render() los valores almacenados en todo momento del 'estado':

        <h3>Datos Ingresados</h3>
        <p>Nombre:{this.state.nombre}</p>
        <p>Edad:{this.state.edad}</p>
        <p>Estudios:{this.state.estudio ? 'con estudios':'sin estudios'}</p>        
      </div>
    );
  }

En los métodos cambioNombre, cambioEdad y cambioEstudio actualizamos el 'estado' llamando al método setState (recordemos que esto hace que se actualice la página solo en aquellos lugares que lo necesiten):

  cambioNombre(e) {
    this.setState( {
      nombre: e.target.value
    })
  }

  cambioEdad(e) {
    this.setState( {
      edad: e.target.value
    })
  }  

  cambioEstudio(e) {
    this.setState( {
      estudio: !this.state.estudio
    })
  }    
}