Voici un élément de base. Les deux <ul>
et <li>
ont des fonctions onClick. Je veux que seul le onClick sur le <li>
se déclenche, pas le <ul>
. Comment puis-je atteindre cet objectif?
J'ai joué avec e.preventDefault (), e.stopPropagation (), en vain.
class List extends React.Component {
constructor(props) {
super(props);
}
handleClick() {
// do something
}
render() {
return (
<ul
onClick={(e) => {
console.log('parent');
this.handleClick();
}}
>
<li
onClick={(e) => {
console.log('child');
// prevent default? prevent propagation?
this.handleClick();
}}
>
</li>
</ul>
)
}
}
// => parent
// => child
reactjs
onclick
event-propagation
dmwong2268
la source
la source
Réponses:
J'ai eu le même problème. J'ai trouvé stopPropagation a fait le travail. Je diviserais l'élément de liste en un composant séparé, comme suit:
la source
this.props.handleClick()
dans leListItem
composantthis.props.click
?<Link>
React utilise la délégation d'événement avec un seul écouteur d'événement sur le document pour les événements qui bouillonnent, comme «clic» dans cet exemple, ce qui signifie que l'arrêt de la propagation n'est pas possible; l'événement réel s'est déjà propagé au moment où vous interagissez avec lui dans React. stopPropagation sur l'événement synthétique de React est possible car React gère la propagation des événements synthétiques en interne.
la source
document.addEventListener('click')
combiné aveconClick
Sur l'ordre des événements DOM: CAPTURING vs BUBBLING
Il y a deux étapes pour la façon dont les événements se propagent. Celles-ci sont appelées «capturer» et «bouillonner» .
L'étape de capture se produit en premier, puis est suivie de l'étape de bouillonnement. Lorsque vous enregistrez un événement à l'aide de l'API DOM standard, les événements feront partie de l'étape de bouillonnement par défaut, mais cela peut être spécifié lors de la création de l'événement
Dans React, les événements de bullage sont également ce que vous utilisez par défaut.
Jetons un œil à l'intérieur de notre callback handleClick (React):
Une alternative que je n'ai pas vue mentionnée ici
Si vous appelez e.preventDefault () dans tous vos événements, vous pouvez vérifier si un événement a déjà été géré et empêcher qu'il ne soit à nouveau traité:
Pour connaître la différence entre les événements synthétiques et les événements natifs, consultez la documentation React: https://reactjs.org/docs/events.html
la source
Ce n'est pas l'idéal à 100%, mais si c'est trop pénible à transmettre
props
aux enfants -> mode pour enfants ou créer unContext.Provider
/Context.Consumer
juste à cette fin), et que vous avez affaire à une autre bibliothèque qui a son propre gestionnaire, elle fonctionne avant le vôtre, vous pouvez également essayer:D'après ce que je comprends, la
event.persist
méthode empêche un objet d'être immédiatement renvoyé dans leSyntheticEvent
pool de React . Donc, à cause de cela, leevent
passé dans React n'existe pas au moment où vous l'atteignez! Cela se produit chez les petits-enfants à cause de la façon dont React gère les choses en interne en vérifiant d'abord parent activé pour lesSyntheticEvent
gestionnaires (surtout si le parent avait un rappel).Tant que vous ne faites pas appel
persist
à quelque chose qui créerait une mémoire importante pour continuer à créer des événements tels queonMouseMove
(et que vous ne créez pas une sorte de jeu Cookie Clicker comme Grandma's Cookies), cela devrait être parfaitement bien!Notez également: en lisant occasionnellement autour de leur GitHub, nous devrions garder les yeux ouverts pour les futures versions de React car elles pourraient éventuellement résoudre une partie de la douleur avec cela car elles semblent aller vers le pliage du code React dans un compilateur / transpilateur.
la source
J'ai eu du mal à
event.stopPropagation()
travailler. Si vous le faites aussi, essayez de le déplacer vers le haut de votre fonction de gestionnaire de clics, c'est ce que je devais faire pour empêcher l'événement de bouillonner. Exemple de fonction:la source
Vous pouvez éviter le bouillonnement d'événement en vérifiant la cible de l'événement.
Par exemple, si vous avez une entrée imbriquée dans l'élément div où vous avez un gestionnaire pour l'événement de clic, et que vous ne voulez pas le gérer, lorsque vous cliquez sur l'entrée, vous pouvez simplement passer
event.target
dans votre gestionnaire et vérifier si le gestionnaire doit être exécuté en fonction de propriétés de la cible.Par exemple, vous pouvez vérifier
if (target.localName === "input") { return}
.Donc, c'est un moyen "d'éviter" l'exécution du gestionnaire
la source
La nouvelle façon de procéder est beaucoup plus simple et vous fera gagner du temps! Passez simplement l'événement dans le gestionnaire de clic d'origine et appelez
preventDefault();
.la source