Fermer

mai 30, 2019

L'expérience du développeur (partie 3)


Si vous avez suivi cette petite série d’articles, vous avez maintenant appris à créer votre propre bibliothèque de validation. Il peut gérer presque tous les défis que vous pouvez lui lancer, et il aide même à résoudre les problèmes d'accessibilité! Son seul inconvénient, c’est que c’est chiant de travailler.

Oui, c’est vrai. L'expérience utilisateur du point de vue du développeur fait cruellement défaut. Nous ne recevons aucun avertissement utile lorsque nous orthographions mal les mots, utilisions mal les API ou, enfin, quoi que ce soit vraiment!

Cet article explique comment améliorer l'expérience de développeur de votre bibliothèque de validation – ou de toute autre bibliothèque à cet effet. .

Démarrer

Depuis la dernière partie de cet article, nous avons extrait tout le code de bibliothèque dans ses propres fichiers. Jetez un coup d’œil à la démonstration de CodeSandbox pour voir ce que nous commençons.

Fonctions de commodité

Nous voulons que notre bibliothèque soit aussi simple que possible à utiliser pour les cas les plus courants. Une façon de progresser vers cet objectif consiste à ajouter des fonctions utilitaires pratiques pour certaines fonctionnalités.

L'une de ces fonctionnalités pourrait être de vérifier si notre formulaire est valide, c'est-à-dire si tous les messages d'erreur sont null . C'est quelque chose que vous vérifiez habituellement dans votre gestionnaire onSubmit mais cela pourrait aussi être utile dans votre méthode de rendu. Implémentons-le!

 const isFormValid = useMemo (
  () => Object.values ​​(errors) .every (error => error === null),
  [errors]
)

Nous fournirons ce drapeau dans notre onSubmit ainsi que dans notre méthode de rendu.

Il y en a beaucoup plus qui pourraient être écrits, mais je vais laisser cela être. un exercice pour le lecteur.

Avertissements de développement et invariants

L’une des fonctionnalités les plus intéressantes de React est les nombreux avertissements utiles qui lui sont apportés sur la console au cours du développement. Nous devons également fournir le même type de qualité à nos utilisateurs.

Pour commencer, nous allons créer deux fonctions: warning (1945), pour enregistrer les avertissements sur la console, et invariant . pour renvoyer une erreur - les deux si une condition donnée n'est pas remplie.

 warning de la fonction (condition, message) {
  if (process.env.NODE_ENV === 'production' || condition) {
    revenir;
  }

  console.warn ('useValidation:' + message);
}
invariant de fonction (condition, message) {
  if (process.env.NODE_ENV === 'production' || condition) {
    revenir;
  }

  jeter une nouvelle erreur ('useValidation:' + message);
}

Vous voulez utiliser invariant si l'erreur va écraser votre bibliothèque (ou la rendre inutile), et warning pour mauvaise pratique ou autre conseil.

When To Warn

Décider quand avertir est très important. Trop, et vous êtes juste ennuyeux. Trop peu, et vous laissez les bogues critiques expédier en production. Par conséquent, nous devons être intelligents avec nos avertissements.

Comme notre bibliothèque accepte un objet de configuration assez volumineux, il est logique de le valider d’une manière ou d’une autre - au moins pendant le développement. Nous pourrions le résoudre en utilisant un système de types tel que TypeScript ou Flow, mais cela exclut tous les utilisateurs JavaScript classiques.

A la place, créons un vérificateur de schéma d'exécution, validant que la configuration contient les champs corrects et imprimons en conséquence. avertissements.

 function validateConfigSchema (config) {
  if (process.env.NODE_ENV === 'production') {
    revenir;
  }
  if (typeof config === 'fonction') {
    config = config ({});
  }

  invariant (
    typeof config === 'objet',
    `useValidation doit être appelé avec un objet ou une fonction renvoyant un objet. Vous avez passé un $ {typeof config} .`,
  )

  invariant (
    typeof config.fields === 'objet',
    'useValidation nécessite un prop de `field` avec un objet contenant les champs et leurs validateurs. Veuillez vous référer à la documentation d'utilisation: https://link.to/docs '
  )

  
  invariant (
    Object.values ​​(config.fields) .every (field => typeof field === 'object'),
    'useValidation nécessite que l'objet `field` ne contienne que des objets. Il semble que le vôtre ne soit pas. Veuillez vous référer à la documentation d'utilisation: https://link.to/docs '
  )

  Attention(
    ['always', 'blur', 'submit', undefined] .includes (config.showError),
    'useValidation a reçu une valeur non prise en charge dans la propriété `showError`. Les valeurs valides sont "Toujours", "Flou" ou "Soumettre". '
  )

  // Etc
}

Nous pourrions probablement continuer à le faire pendant un certain temps si nous voulions passer le temps. Et vous devriez! C’est un excellent moyen d’améliorer l’expérience de développeur de votre application.

Cependant, vous n’avez pas besoin de les écrire à la main. Il existe un port de navigateur de la bibliothèque de validation de schéma d’objet très répandue joi qui pourrait vous aider à créer une vérification de validation d’exécution vraiment agréable. De plus, comme mentionné précédemment, un système de types aiderait à détecter les erreurs de configuration lors de la compilation pour les utilisateurs qui utilisent ce système.

Autoriser la flexibilité

Une bonne expérience de développeur n’empêche en grande partie pas la développeurs. Voyons quelques moyens d’améliorer cette expérience.

Composez-en des accessoires conflictuels

Premièrement, nos accesseurs appliquent des accessoires à nos intrants et formes qui peuvent être ignorées accidentellement par nos consommateurs. Ajoutons plutôt un objet de substitution d’accessoires à nos accesseurs d’accessoires, qui composeront tous les accessoires en conflit.

Voici comment nous pouvons l’appliquer dans notre getFieldProps :

.
getFieldProps: (fieldName, overrides = {}) => ({
  onChange: e => {
    const {valeur} = e.target;
    if (! config.fields [fieldName]) {
      revenir;
    }
    envoi({
      type: 'change',
      charge utile: {[fieldName]: valeur},
    });
    if (overrides.onChange) {
      overrides.onChange (e);
    }
  },
  onBlur: e => {
    dispatch ({type: 'blur', charge utile: nom du champ});
    if (overrides.onBlur) {
      overrides.onBlur (e)
    }
  },
  nom: overrides.name || nom de domaine,
  valeur: state.values ​​[fieldName] || '',
}),

Une approche similaire peut être suivie dans de getFormProps .

Aide à éviter le forage de puits

Certaines formes peuvent être volumineuses et divisées en plusieurs composants. Au lieu de placer les accessoires de forage de nos consommateurs dans l’arbre, nous devrions fournir un contexte. De cette façon, ils peuvent accéder à tous les éléments que nous renvoyons à partir de notre crochet personnalisé n'importe où dans l'arbre ci-dessous.

Commençons par créer un ValidationContext avec la méthode createContext de React:

 export const ValidationContext = React. createContext ({});

Créons ensuite un composant ValidationProvider qui fournit toutes les valeurs du hook useValidation en contexte:

 export const ValidationProvider = props => {
  const contexte = useValidation (props.config);
  revenir (
    
      {props.children}
    
  )
};

Maintenant, au lieu d'appeler useValidation directement, nous enroulerions notre formulaire dans un composant ValidationProvider et accéderions aux accessoires de validation ( getFormProps erreurs etc.) en utilisant le crochet useContext . Vous l’utiliseriez comme ceci:

 Import React, {useContext} de 'react';
importer {ValidationContext} de './useValidation';

fonction UsernameForm (props) {
  const {getFieldProps, errors} = useContext (ValidationContext);
  revenir (
    <>
      
      {errors.username &&  {errors.username}> }
    
  )
}
 

De cette façon, vous obtenez le meilleur des deux mondes! Vous obtenez un crochet simple pour ces scénarios simples et la flexibilité dont vous avez besoin pour ces pièces complexes.

La documentation est essentielle

Chaque fois que j'utilise une bibliothèque que je n'ai pas écrite moi-même, j'aime une excellente documentation. . Mais sur quoi devriez-vous vous concentrer et où devriez-vous documenter?

Une première étape devrait consister à créer un fichier README simple à comprendre, avec les exemples d'utilisation les plus élémentaires facilement disponibles. Andrew Healey a écrit un article étonnant sur comment écrire un bon fichier README que je vous recommande vivement de lire.

Lorsque vous avez créé un bon fichier README pour faire avancer les gens, un site de documentation pourrait être une bonne idée. Ici, vous pouvez mettre une documentation plus détaillée sur l’API, des recettes pour des cas d’utilisation typiques et une bonne vieille FAQ.

Il existe d’excellents outils pour générer des sites Web de documentation. Mon préféré est docusaurus de Facebook (humble vantard: nous l'avons utilisé lors de la création du site Web create-react-app ), mais il existe plusieurs alternatives intéressantes. [19659004] Nous n'allons pas vous expliquer comment rédiger une bonne documentation dans cet article. Il existe plusieurs bons articles - même une communauté appelée « Write the Docs ». Ils ont écrit un excellent guide sur la comment commencer à rédiger une bonne documentation .

Résumé

Grâce à cette série d’articles, nous avons créé une bibliothèque de validation assez décente. Il possède une API assez simple, une flexibilité pour quand vous en avez besoin, une bonne expérience de développeur et de nombreuses fonctionnalités assez danks.

Nous avons déjà expliqué comment nous avons implémenté les choses étape par étape, et j'espère que vous en apprendrez plus. comprendre comment vous pouvez créer votre propre bibliothèque et comment vous en ferez quelque chose que les gens aimeraient utiliser.

Faites-le-moi savoir dans les commentaires, ce que vous pensez, et si vous y étiez en partie sur un ou plusieurs morceaux temps de compréhension. Je ferai de mon mieux pour mettre à jour cet article à mesure que les commentaires s'en mêlent.

Pour terminer cet article, voici la version finale:

Merci d'avoir lu

 Smashing Editorial (dm, yk, il )




Source link