3
votes

L'état enregistré du hook React dans Event Listener est incorrect?

J'ai des points et une fonction pour mettre à jour les points:

window.google.maps.event.addListener(marker, 'dragend',
  function (markerLocal) {
    console.log(getPoints)       
  }
)

J'ai ajouté un auditeur au marqueur:

const [points, setPoints] = useState([])

const updatePoint = (updatedPoint) => {
  setPoints(points.map(point => (point.id === updatedPoint.id ? updatedPoint : point)))
}

Si Je clique sur le premier marqueur après l'avoir créé, il me montre 1 point dans la console. Si je crée et clique en deuxième, cela me montre 2 points, donc il enregistre l'état à l'intérieur de l'auditeur. Cependant, après la deuxième sauvegarde, la somme des points du premier marqueur ne change pas (quand il est déplacé). Est-ce le bon comportement? Comment puis-je obtenir deux points pour le premier marqueur? Chaque fois que j'essaye de mettre à jour ma liste de points et que je clique sur le premier marqueur, cela ne me donne qu'un seul point - c'est faux.


1 commentaires

Je pense que vous devrez peut-être afficher davantage de votre code - qu'est-ce que getPoints ? Où installez-vous vos auditeurs?


3 Réponses :


1
votes

Ceci est probablement dû au fait que le gestionnaire utilise les points au moment de la déclaration, qui peuvent être mis à jour avant d'être appelés. Ma solution à ces problèmes était de le définir comme une référence:

const points = useRef([]);
// This means that instead of `setPoints` you will do points.current = newValue

const updatePoint = (updatePoint) => {
   points.current = points.current.map(...);
}


0 commentaires

1
votes

Si un état précédent est utilisé pour calculer le nouvel état, comme dans votre exemple, vous devez passer setPoints () une fonction de l'ancien état au lieu de la nouvelle valeur directement:

const updatePoint = (updatedPoint) => {
  setPoints((prevPoints) =>
      prevPoints.map(point => (point.id === updatedPoint.id ? updatedPoint : point)
  ))
}

Section pertinente de la référence de l'API Hooks: Mises à jour fonctionnelles pour useState


0 commentaires

4
votes

Essayez d'ajouter useEffect avec une dépendance points et définissez addEventListener pour google maps. Un problème ici est la portée sur laquelle le addEventListener initial travaille. Dans le JS standard, vous auriez toujours la valeur actuelle dans la portée, cependant, dans les hooks, votre code référencera les valeurs périmées des rendus précédents. Dans votre cas, vous faites référence aux valeurs de votre état de points au moment de la connexion de l'événement à Google Maps. La solution la plus propre ici, à mon avis, est celle de Leftium, mais vous pouvez également essayer celle-ci à des fins 'académiques':

const onGoogleMapsMarkerDragend = () => {
    console.log(points);
}
useEffect(() => {
    const dragendListener = window.google.maps.event.addListener(marker, 'dragend', onGoogleMapsMarkerDragend);
    return () => {
        window.google.maps.event.removeListener(dragendListener );
    }
}, [points];

Je ne sais pas si removeListener est valide - vérifiez avec la documentation


0 commentaires