Ajout dynamique de nouveaux champs à un formulaire avec React.js

Nov 29 2022
Je travaillais récemment sur un projet où je devais ajouter conditionnellement des champs à un formulaire et permettre aux utilisateurs d'ajouter plus de champs à la volée selon leurs besoins. Au début, cela semblait difficile et comme le développeur paresseux que je suis, j'ai cherché sur Google si quelqu'un avait fait quelque chose de similaire, mais je n'en ai pas trouvé, alors j'ai décidé d'en créer un à partir de zéro.

Je travaillais récemment sur un projet où je devais ajouter conditionnellement des champs à un formulaire et permettre aux utilisateurs d'ajouter plus de champs à la volée selon leurs besoins. Au début, cela semblait difficile et comme le développeur paresseux que je suis, j'ai cherché sur Google si quelqu'un avait fait quelque chose de similaire, mais je n'en ai pas trouvé, alors j'ai décidé d'en créer un à partir de zéro. Ce qui suit est ma tentative naïve de résoudre le problème que je viens de décrire. Ce n'est pas une solution parfaite et j'aimerais avoir des commentaires sur la façon de l'améliorer.

La première chose que j'ai faite a été de décomposer le problème en plus petits morceaux afin que je puisse mieux y réfléchir. J'ai remarqué que le formulaire devait faire quelques choses.

  1. Créez une nouvelle ligne de formulaire.
  2. Créez de nouveaux champs et ajoutez les champs à la nouvelle ligne créée.
  3. Ajouter la nouvelle ligne au formulaire d'origine
  4. Gérez l'état des éléments de ligne à partir du formulaire.

Je suis donc allé de l'avant et j'ai créé les composants pour représenter les étapes décrites ci-dessus. J'ai d'abord créé les champs comme indiqué dans l'extrait de code ci-dessous.

La prochaine chose que je devais faire était de trouver un moyen de garder une trace de tous ces composants créés afin que notre formulaire soit rempli avec ceux-ci. Pour résoudre ce problème, j'ai créé un autre composant qui agira en tant que composant parent, en gardant une trace du nombre d'éléments de ligne créés et en les affichant au fur et à mesure de leur création.

Le composant démarre avec une FormLine. Lorsque l'utilisateur clique sur le bouton Ajouter un élément, un nouveau composant FormLine est ajouté à la liste des composants et le composant parent est restitué, affichant le composant nouvellement ajouté.

Maintenant que nous avons résolu les trois premiers problèmes, le dernier problème et peut-être le plus intéressant est de savoir comment gérer l'état des éléments de campagne à partir du composant parent. La première approche que j'ai utilisée consistait à envoyer l'état de l'ensemble du composant de l'élément de ligne au composant parent lorsque l'utilisateur brouille le dernier champ de saisie de l'élément de ligne. Cependant, j'ai vite découvert que l'approche ne s'adapte pas bien, par exemple, lorsque l'utilisateur tape dans les deux champs et s'estompe, mais revient ensuite au premier composant d'entrée et apporte une correction, nous perdons cette information.

Pour résoudre ce problème, j'ai décidé que pousser l'état du composant de ligne vers le composant parent sur le flou de chaque champ serait la meilleure approche ici. Pour y parvenir, nous aurions besoin de maintenir une liste d'éléments permettant au composant d'ajouter de nouveaux éléments à la liste et de modifier un élément de la liste. Pour ce faire, j'avais besoin d'ajouter un champ d'index à l'état de chaque élément de ligne afin que je puisse facilement trouver et modifier en cas de besoin. J'ai modifié le composant FormLine pour prendre la fonction qui transmet son état au composant parent comme accessoire.

Dans le composant parent FormLineItems, j'ai écrit la fonction pushItem et je l'ai transmise au composant en tant que prop. Le composant ressemble maintenant à ceci :

Désormais, lorsque vous tapez du texte dans les champs et que vous cliquez sur ajouter un élément, vous devriez voir l'état actuel du composant affiché au-dessus des champs de texte.

Vous pouvez trouver le code de cet article surhttps://gist.github.com/vdugeri/0a9f1972b80918b624e71b9aab35cb8e