Comment j'ai résolu un problème avec un état de formulaire de connexion React et le remplissage automatique du navigateur

Je suis tombé sur un problème en travaillant sur un projet dont j'avais créé un formulaire à l'aide de React et sur la manière dont le remplissage automatique du navigateur interagissait avec celui-ci.

Vous savez, quand le navigateur met automatiquement votre nom d'utilisateur / mot de passe parce que vous l'avez déjà tapé dans le passé?

C'est le remplissage automatique, et c'est la cause de mon problème. En particulier, je l'ai répliqué sur Chrome et Firefox, mais n'importe quel navigateur peut rencontrer cela.

La forme était une forme habituelle et simple construite avec leuseStateaccrocher.

Voici un exempleemailchamp du formulaire:

import { useState } from 'react'

//… const [email, setEmail] = useState(’’)

<input
id=‘email’
type=‘email’
name=‘email’ value={email} onChange={(event) => setEmail(event.target.value)} />

Lorsque vous saisissez l'e-mail, leemailla valeur est mise à jour à l'aide desetEmailet je l'aurai disponible sur l'événement de soumission de formulaire, afin que je puisse l'envoyer au serveur.

À un moment donné, j'ai réalisé que le navigateur remplissait automatiquement l'e-mail et le mot de passe, mais React ne l'a pas reconnu!

Peut-être parce qu'il remplit le champ avant que React ne soit complètement exécuté, il ne peut donc pas intercepter cet événement.

J'ai fait un peu de recherche et je me suis perdu dans un pays d'incohérences de navigateur et de différences dans le fonctionnement du remplissage automatique, j'ai donc dû créer une solution de contournement simple.

Je l'ai fait en utilisantuseRefetuseEffect:

import { useState, useEffect, useRef } from 'react'

Je crée une ref:

const emailField = useRef(null)

et dans le JSX je l'attache au champ de saisie:

<input
  ref={emailField}
  id='email'
  type='email'                   
  name='email'
  value={email}
  onChange={(event) => setEmail(event.target.value)} 
/>

Ensuite, j'ai ajouté un morceau de code qui toutes les 100 ms recherche la valeur du champ et appellesetEmail()pour le mettre à jour:

useEffect(() => {
  let interval = setInterval(() => {
    if (emailField.current) {
      setEmail(emailField.current.value)
      //do the same for all autofilled fields
      clearInterval(interval)
    }
  }, 100)
})

Ce n'est pas idéal, cela implique une manipulation DOM, ce que nous devrions éviter lors de l'utilisation d'une bibliothèque comme React, mais cela fonctionne autour de ce problème.

Et s'il n'y a pas de remplissage automatique? Cela attendra simplement que le premier caractère soit tapé et arrêtera la boucle.

Téléchargez mon gratuitManuel React


Plus de tutoriels de réaction: