Creación de su propia biblioteca de validación de React: las características (Parte 2)

 

 

 

  • Planificación y proceso del sistema de diseño, con Nathan Curtis
  • ¡Registro!

  • Índice
    1. Mostrar solo validación al enviar
    2. Mostrar mensajes de error en desenfoque
    3. Es hora de una pequeña refactorización
    4. Permitir validación cruzada
    5. Agregue algunas ventajas de accesibilidad
      1. Sintaxis abreviada del mensaje de validación
    6. Valores de campo iniciales
    7. Resumiendo

    En el artículo anterior, Kristofer explicó cómo se pueden implementar las partes básicas de una biblioteca de validación. Si bien la siguiente parte se centrará en mejorar la experiencia del desarrollador, el artículo de hoy se centrará en agregar más funciones a lo que se creó en la Parte 1 .

     

    Implementar una biblioteca de validación no es tan difícil. Tampoco lo es agregar todas esas características adicionales que hacen que su biblioteca de validación sea mucho mejor que el resto.

    Este artículo continuará implementando la biblioteca de validación que comenzamos a implementar en la parte anterior de esta serie de artículos. ¡Estas son las características que nos llevarán de una simple prueba de concepto a una biblioteca utilizable real!

    • Parte 1: Conceptos básicos
    • Parte 2: Las características
    • Parte 3: La experiencia

    Mostrar solo validación al enviar

    Dado que estamos validando todos los eventos de cambio, mostramos los mensajes de error del usuario demasiado pronto para una buena experiencia de usuario. Hay algunas formas en que podemos mitigar esto.

    La primera solución es simplemente proporcionar la submittedbandera como una propiedad devuelta por el useValidationgancho. De esta forma podremos comprobar si el formulario se envía o no antes de mostrar un mensaje de error. La desventaja aquí es que nuestro "mostrar código de error" se vuelve un poco más largo:

    label Username br / input {...getFieldProps('username')} / {submitted errors.username ( div className="error"{errors.username}/div )}/label

    Otro enfoque es proporcionar un segundo conjunto de errores (llamémoslos submittedErrors), que es un objeto vacío si submittedes falso y el errorsobjeto si es verdadero. Podemos implementarlo así:

     

    const useValidation = config = { // as before return { errors: state.errors, submittedErrors: state.submitted ? state.errors : {}, };}

    De esta manera, podemos simplemente desestructurar el tipo de errores que queremos mostrar. Por supuesto, también podríamos hacer esto en el sitio de la llamada, pero al proporcionarlo aquí, lo implementaremos una vez en lugar de hacerlo dentro de todos los consumidores.

    • Vea la demostración de CodeSandbox que muestra cómo submittedErrorsse puede utilizar.

    Mostrar mensajes de error en desenfoque

    Mucha gente quiere que se les muestre un error una vez que abandonan un determinado campo. Podemos agregar soporte para esto, rastreando qué campos se han "difuminado" (alejándose de ellos) y devolviendo un objeto blurredErrors, similar al submittedErrorsanterior.

    La implementación requiere que manejemos un nuevo tipo de acción blur, que actualizará un nuevo objeto de estado llamado blurred:

    const initialState = { values: {}, errors: {}, blurred: {}, submitted: false,};function validationReducer(state, action) { switch (action.type) { // as before case 'blur': const blurred = { ...state.blurred, [action.payload]: true }; return { ...state, blurred }; default: throw new Error('Unknown action type'); }}

    Cuando enviamos la bluracción, creamos una nueva propiedad en el blurredobjeto de estado con el nombre del campo como clave, lo que indica que ese campo se ha desdibujado.

    El siguiente paso es agregar un onBluraccesorio a nuestra getFieldPropsfunción, que envíe esta acción cuando corresponda:

    getFieldProps: fieldName = ({ // as before onBlur: () = { dispatch({ type: 'blur', payload: fieldName }); },}),

    Finalmente, debemos proporcionar blurredErrorsdesde nuestro useValidationenlace para que podamos mostrar los errores solo cuando sea necesario.

    const blurredErrors = useMemo(() = { const returnValue = {}; for (let fieldName in state.errors) { returnValue[fieldName] = state.blurred[fieldName] ? state.errors[fieldName] : null; } return returnValue; }, [state.errors, state.blurred]);return { // as before blurredErrors,};

    Aquí, creamos una función memorizada que determina qué errores mostrar en función de si el campo se ha difuminado o no. Recalculamos este conjunto de errores cada vez que cambian los errores u objetos borrosos. Puedes leer más sobre el useMemogancho en la documentación .

    • Ver demostración de CodeSandbox

    Es hora de una pequeña refactorización

    Nuestro useValidationcomponente ahora devuelve tres conjuntos de errores, la mayoría de los cuales tendrán el mismo aspecto en algún momento. En lugar de seguir esta ruta, permitiremos que el usuario especifique en la configuración cuándo quiere que aparezcan los errores en su formulario.

     

    Nuestra nueva opción showErrorsaceptará "enviar" (el valor predeterminado), "siempre" o "desenfocar". Podemos agregar más opciones más adelante, si es necesario.

    function getErrors(state, config) { if (config.showErrors === 'always') { return state.errors; } if (config.showErrors === 'blur') { return Object.entries(state.blurred) .filter(([, blurred]) = blurred) .reduce((acc, [name]) = ({ ...acc, [name]: state.errors[name] }), {}); } return state.submitted ? state.errors : {};}const useValidation = config = { // as before const errors = useMemo( () = getErrors(state, config), [state, config] ); return { errors, // as before };};

    Dado que el código de manejo de errores comenzó a ocupar la mayor parte de nuestro espacio, lo estamos refactorizando para que tenga su propia función. Si no sigues las instrucciones Object.entriesy .reducedemás, está bien, es una reescritura del for...incódigo en la última sección.

    Si requiriéramos onBlur o validación instantánea, podríamos especificar el showErroraccesorio en nuestro useValidationobjeto de configuración. Podcast ingles diario

    const config = { // as before showErrors: 'blur',};const { getFormProps, getFieldProps, errors } = useValidation(config);// errors would now only include the ones that have been blurred
    • Ver demostración de CodeSandbox

    Nota sobre supuestos

    “Tenga en cuenta que ahora estoy asumiendo que cada formulario querrá mostrar los errores de la misma manera (siempre al enviar, siempre borrosos, etc.). Esto podría ser cierto para la mayoría de las aplicaciones, pero probablemente no para todas. Ser consciente de sus suposiciones es una parte muy importante de la creación de su API ".

    Permitir validación cruzada

    Una característica realmente poderosa de una biblioteca de validación es permitir la validación cruzada, es decir, basar la validación de un campo en el valor de otro campo.

    Para permitir esto, necesitamos hacer que nuestro gancho personalizado acepte una función en lugar de un objeto. Esta función se llamará con los valores de campo actuales. ¡Implementarlo en realidad son solo tres líneas de código!

    function useValidation(config) { const [state, dispatch] = useReducer(...); if (typeof config === 'function') { config = config(state.values); }}

    Para usar esta característica, simplemente podemos pasar una función que devuelva el objeto de configuración a useValidation:

    const { getFieldProps } = useValidation(fields = ({ password: { isRequired: { message: 'Please fill out the password' }, }, repeatPassword: { isRequired: { message: 'Please fill out the password one more time' }, isEqual: { value: fields.password, message: 'Your passwords don’t match' } }}));

    Aquí, usamos el valor de fields.passwordpara asegurarnos de que dos campos de contraseña contengan la misma entrada (lo cual es una experiencia de usuario terrible, pero eso es para otra publicación de blog).

     

    • Vea la demostración de CodeSandbox que no permite que el nombre de usuario y la contraseña tengan el mismo valor.

    Agregue algunas ventajas de accesibilidad

    Una buena cosa que puedes hacer cuando estás a cargo de los accesorios de un campo es agregar las etiquetas aria correctas de forma predeterminada. Esto ayudará a los lectores de pantalla a explicar su formulario.

    Una mejora muy sencilla es agregar aria-invalid="true"si el campo tiene algún error. Implementemos eso:

    const useValidation = config = { // as before return { // as before getFieldProps: fieldName = ({ // as before 'aria-invalid': String(!!errors[fieldName]), }), }};

    Esa es una línea de código adicional y una experiencia de usuario mucho mejor para los usuarios de lectores de pantalla.

    Quizás te preguntes por qué escribimos String(!!state.errors[fieldName]). state.errors[fieldName]es una cadena, y el operador de doble negación nos da un valor booleano (y no sólo un valor verdadero o falso). Sin embargo, la aria-invalidpropiedad debe ser una cadena (también puede leerse “gramática” u “ortografía”, además de “verdadero” o “falso”), por lo que debemos convertir ese booleano en su equivalente de cadena.

    Todavía quedan algunos ajustes más que podríamos hacer para mejorar la accesibilidad, pero parece un buen comienzo.

    Sintaxis abreviada del mensaje de validación

    La mayoría de los validadores del calidatorspaquete (y supongo que la mayoría de los demás validadores) solo requieren un mensaje de error. ¿No sería bueno si pudiéramos pasar esa cadena en lugar de un objeto con una messagepropiedad que contenga esa cadena?

    Implementemos eso en nuestra validateFieldfunción:

    function validateField(fieldValue = '', fieldConfig, allFieldValues) { for (let validatorName in fieldConfig) { let validatorConfig = fieldConfig[validatorName]; if (typeof validatorConfig === ’string') { validatorConfig = { message: validatorConfig }; } const configuredValidator = validators[validatorName](validatorConfig); const errorMessage = configuredValidator(fieldValue); if (errorMessage) { return errorMessage; } } return null;}

    De esta manera, podemos reescribir nuestra configuración de validación así:

    const config = { username: { isRequired: 'The username is required', isEmail: 'The username should be a valid email address', },};

    ¡Mucho más limpio!

    Valores de campo iniciales

    A veces necesitamos validar un formulario que ya está completo. Nuestro gancho personalizado aún no admite eso, ¡así que vamos a ello!

    Los valores de campo iniciales se especificarán en la configuración de cada campo, en la propiedad initialValue. Si no se especifica, el valor predeterminado es una cadena vacía.

    Vamos a crear una función getInitialState, que creará el estado inicial de nuestro reductor por nosotros.

    function getInitialState(config) { if (typeof config === 'function') { config = config({}); } const initialValues = {}; const initialBlurred = {}; for (let fieldName in config.fields) { initialValues[fieldName] = config.fields[fieldName].initialValue || ''; initialBlurred[fieldName] = false; } const initialErrors = validateFields(initialValues, config.fields); return { values: initialValues, errors: initialErrors, blurred: initialBlurred, submitted: false, };}

    Revisamos todos los campos, comprobamos si tienen una initialValuepropiedad y establecemos el valor inicial en consecuencia. Luego pasamos esos valores iniciales a través de los validadores y también calculamos los errores iniciales. Devolvemos el objeto de estado inicial, que luego se puede pasar a nuestro useReducergancho.

    Dado que estamos introduciendo un accesorio no validador en la configuración de campos, debemos omitirlo cuando validemos nuestros campos. Para hacer eso, cambiamos nuestra validateFieldfunción:

    function validateField(fieldValue = '', fieldConfig) { const specialProps = ['initialValue']; for (let validatorName in fieldConfig) { if (specialProps.includes(validatorName)) { continue; } // as before }}

    A medida que sigamos agregando más funciones como esta, podemos agregarlas a nuestra specialPropsmatriz.

    • Ver demostración de CodeSandbox

    Resumiendo

    Estamos en camino de crear una increíble biblioteca de validación. Hemos agregado toneladas de funciones y ya somos líderes de opinión.

    En la siguiente parte de esta serie, agregaremos todos esos extras que hacen que nuestra biblioteca de validación sea incluso tendencia en LinkedIn.

    (dm, yk, il)Explora más en

    • Reaccionar
    • javascript
    • Pruebas
    • Formularios





    Tal vez te puede interesar:

    1. Creación de su propia biblioteca de validación de React: la experiencia del desarrollador (Parte 3)
    2. Introducción a Quasar Framework: creación de aplicaciones multiplataforma
    3. Creación de un componente web retro que se puede arrastrar con iluminación
    4. Creación y acoplamiento de una aplicación Node.js con arquitectura sin estado con la ayuda de Kinsta

    Creación de su propia biblioteca de validación de React: las características (Parte 2)

    Creación de su propia biblioteca de validación de React: las características (Parte 2)

    Planificación y proceso del sistema de diseño, con Nathan Curtis ¡Registro! Índice Mostrar solo valida

    programar

    es

    https://aprendeprogramando.es/static/images/programar-creacion-de-su-propia-biblioteca-de-validacion-de-react-las-caracteristicas-parte-2-986-0.jpg

    2024-05-20

     

    Creación de su propia biblioteca de validación de React: las características (Parte 2)
    Creación de su propia biblioteca de validación de React: las características (Parte 2)

    Si crees que alguno de los contenidos (texto, imagenes o multimedia) en esta página infringe tus derechos relativos a propiedad intelectual, marcas registradas o cualquier otro de tus derechos, por favor ponte en contacto con nosotros en el mail [email protected] y retiraremos este contenido inmediatamente

     

     

    Top 20