Cómo usar las entradas controladas de React para la validación instantánea de campos de formulario

Las entradas controladas permiten cosas simples, como deshabilitar el botón Enviar cuando faltan algunos campos o no son válidos.

Pero no nos detendremos allí, por supuesto.

Si bien un botón deshabilitado es bueno, es posible que el usuario no sepa por qué no puede hacer clic en ese botón. Es posible que no sepan qué error cometieron que lo deshabilitó o incluso qué campo lo está causando.

Y eso no es bonito. Absolutamente tenemos que arreglar eso.

Los fundamentos de las entradas controladas

El uso de entradas controladas implica que estamos almacenando todos los valores de entrada en nuestro estado. Luego podemos evaluar una condición particular con cada cambio de valor y hacer algo en función de ello. Anteriormente, todo lo que hicimos fue desactivar el botón.

Utilizamos una expresión simple para calcular si el botón debe estar desactivado (por ejemplo, cuando el campo de correo electrónico o contraseña estaba vacío):

const {correo electrónico, contraseña} = this.state;
const isEnabled =
  email.length> 0 &&
  contraseña.length> 0;

Se hizo el trabajo. Ahora, para marcar las entradas incorrectas, debemos hacernos un par de preguntas.

¿Cómo se mostrarán los errores?

Esta es una pregunta importante que debe hacerse, ya que los diferentes requisitos pueden justificar diferentes representaciones de errores.

Hay muchas formas de mostrar errores de entrada. Por ejemplo, podrías:

  • Mostrar un
  • Marque las entradas en rojo que contienen datos incorrectos
  • Mostrar errores justo al lado de las entradas relevantes
  • Mostrar una lista de errores en la parte superior del formulario
  • ¡Cualquier combinación de lo anterior, o algo más!

¿Cual deberías usar? Bueno, se trata de la experiencia que quieres brindar. Elige lo que quieras.

Para el propósito de esta publicación, voy a usar la más simple: marcar las entradas incorrectas en rojo, sin otra cosa.

¿Cómo se representarán los errores?

La forma en que desea mostrar los errores influye en cómo podría representarlos.

Para indicar si una entrada en particular es válida, sin ninguna información adicional de por qué podría ser inválida, algo como esto será suficiente:

errores: {
  nombre: falso
  correo electrónico: verdadero,
}

falso significa que no hay errores o es completamente válido; verdadero significa que un campo no es válido.

En el futuro, si decidimos que necesitamos almacenar la razón por la que algo no era válido, podemos reemplazar el verdadero / falso con una cadena que contiene un mensaje de error.

Pero, ¿cómo se crea este objeto de error?

Ahora que sabemos cómo queremos mostrar los errores Y cómo representarlos, falta algo crucial.

Cómo crear realmente errores.

O, dicho de otra manera: ¿cómo tomamos las entradas existentes, las validamos y obtenemos el objeto de error que necesitamos?

Vamos a necesitar una función de validación para eso. Aceptará los valores actuales de los campos y nos devolverá los errores.

Continuaremos con el ejemplo del formulario de registro. Recordemos que tuvimos esto:

const {correo electrónico, contraseña} = this.state;
const isEnabled =
  email.length> 0 &&
  contraseña.length> 0;

De hecho, podemos convertir esa lógica en una función de validación que:

  • Tener correo electrónico: verdadero si el correo electrónico está vacío, y
  • Tener contraseña: verdadero si la contraseña está vacía
función validar (correo electrónico, contraseña) {
  // verdadero significa inválido, por lo que nuestras condiciones se invirtieron
  regreso {
    correo electrónico: email.length === 0,
    contraseña: contraseña.length === 0,
  };
}

La pieza restante

Queda una pieza del rompecabezas.

Tenemos una función de validación y sabemos cómo queremos mostrar los errores. También tenemos un formulario.

Ahora es el momento de conectar los puntos.

Paso 1: ejecuta el validador en render.

No sirve de nada tener la función de validación si nunca la llamamos. Queremos validar las entradas cada vez (sí, cada vez) el formulario se vuelve a representar, tal vez haya un nuevo carácter en la entrada.

errores constantes = validar (this.state.email, this.state.password);

Paso 2: deshabilita el botón.

Esto es muy simple. El botón debe deshabilitarse si hay algún error (es decir, si alguno de los valores de error es verdadero).

const isEnabled =! Object.keys (errores) .some (x => errores [x]);

Paso 3: Marque las entradas como erróneas.

Esto puede ser cualquier cosa. En nuestro caso, es suficiente agregar una clase de error a las entradas incorrectas.

También podemos agregar una regla CSS simple:

.error {borde: 1px rojo sólido; }

Una cosa más

Si observa el JS Bin arriba, puede notar algo extraño. Los campos están marcados en rojo por defecto, porque los campos vacíos no son válidos.

¡Pero nunca le dimos al usuario la oportunidad de escribir primero! Además, los campos son rojos cuando se enfocan por primera vez.

Esto no es genial para UX.

Vamos a arreglar esto agregando la clase de error si el campo estaba enfocado al menos una vez pero desde entonces se ha desdibujado. Esto garantiza que la primera vez que un usuario se concentre en el campo, el error no aparecerá de inmediato. En cambio, solo aparecerá cuando el campo esté borroso. Sin embargo, en los enfoques posteriores, aparecería el error.

Esto se puede lograr fácilmente mediante el uso del evento y estado onBlur para realizar un seguimiento de lo que fue borroso.

clase SignUpForm extiende React.Component {
  constructor () {
    súper();
    this.state = {
      correo electrónico: '',
      contraseña: '',
      tocado: {
        correo electrónico: falso
        contraseña: falso
      },
    };
  }
  // ...
  handleBlur = (campo) => (evt) => {
    this.setState ({
      tocado: {... this.state.touched, [campo]: verdadero},
    });
  }
  hacer()
    const shouldMarkError = (campo) => {
      const hasError = errores [campo];
      const shouldShow = this.state.touched [campo];
      return hasError? shouldShow: falso;
    };
    // ...
    
      tipo = "texto"
      marcador de posición = "Ingresar correo electrónico"
      valor = {this.state.email}
      onChange = {this.handleEmailChange}
    />
  }
}

No es tan difícil, ¿verdad?

Toques finales

Tenga en cuenta que shouldMarkError solo afecta a la presentación de campo. El estado del botón de envío todavía depende solo de los errores de validación.

¿Quieres agregar un buen toque final? Puede forzar la visualización de errores en todos los campos, independientemente de si se han enfocado, cuando el usuario se desplaza o hace clic en un botón de envío deshabilitado. Ahora ve a probarlo por ti mismo.

Originalmente publiqué esto en mi blog en goshakkk.name

Si estás cavando esto, dame algunos aplausos y mira mi serie sobre cómo manejar formularios con React. También puedes suscribirte para obtener nuevas publicaciones directamente en tu bandeja de entrada.