Aquí tienes un componente básico. Tanto el <ul>
como <li>
tienen funciones onClick. Solo quiero <li>
que se dispare el onClick , no el <ul>
. ¿Cómo puedo conseguir esto?
He jugado con e.preventDefault (), e.stopPropagation (), sin éxito.
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
fuente
fuente
Respuestas:
Tuve el mismo problema. He encontrado stopPropagation hizo el trabajo. Dividiría el elemento de la lista en un componente separado, así:
fuente
this.props.handleClick()
enListItem
componentethis.props.click
?<Link>
React usa la delegación de eventos con un solo detector de eventos en el documento para los eventos que burbujean, como 'clic' en este ejemplo, lo que significa que no es posible detener la propagación; el evento real ya se ha propagado cuando interactúas con él en React. stopPropagation en el evento sintético de React es posible porque React maneja la propagación de eventos sintéticos internamente.
fuente
document.addEventListener('click')
combinado con react'sonClick
En el orden de los eventos DOM: CAPTURAR vs BURBUJAR
Hay dos etapas sobre cómo se propagan los eventos. Estos se denominan "captura" y "burbujeo" .
La etapa de captura ocurre primero y luego es seguida por la etapa de burbujeo. Cuando registra un evento utilizando la API DOM normal, los eventos serán parte de la etapa de burbujeo de forma predeterminada, pero esto se puede especificar al crear el evento.
En React, los eventos de burbujeo también son lo que usa de forma predeterminada.
Echemos un vistazo dentro de nuestro handleClick callback (React):
Una alternativa que no he visto mencionada aquí.
Si llama a e.preventDefault () en todos sus eventos, puede verificar si un evento ya ha sido manejado y evitar que se maneje nuevamente:
Para conocer la diferencia entre eventos sintéticos y eventos nativos, consulte la documentación de React: https://reactjs.org/docs/events.html
fuente
Esto no es 100% ideal, pero si es demasiado doloroso transmitirlo a los
props
niños -> moda infantil o crear unContext.Provider
/Context.Consumer
solo para este propósito), y está tratando con otra biblioteca que tiene su propio controlador que ejecuta antes que el tuyo, también puedes probar:Por lo que tengo entendido, el
event.persist
método evita que un objeto sea devuelto inmediatamente al grupo de ReactSyntheticEvent
. Entonces, debido a eso, ¡elevent
aprobado en React en realidad no existe para cuando lo alcanzas! Esto sucede en los nietos debido a la forma en que React maneja las cosas internamente al verificar primero al padre en busca deSyntheticEvent
controladores (especialmente si el padre tuvo una devolución de llamada).Siempre que no invoques
persist
algo que pueda crear una memoria significativa para seguir creando eventos comoonMouseMove
(y no estés creando algún tipo de juego de Cookie Clicker como Grandma's Cookies), ¡debería estar perfectamente bien!También tenga en cuenta: de leer alrededor de su GitHub ocasionalmente, debemos estar atentos a las futuras versiones de React, ya que eventualmente pueden resolver algunos de los problemas con esto, ya que parecen estar dirigidos a hacer un código React plegable en un compilador / transpilador.
fuente
Tuve problemas para
event.stopPropagation()
trabajar. Si lo hace también, intente moverlo a la parte superior de la función de control de clics, eso era lo que tenía que hacer para evitar que el evento se propagara. Función de ejemplo:fuente
Puede evitar la propagación de eventos marcando el destino del evento.
Por ejemplo, si tiene una entrada anidada en el elemento div donde tiene un controlador para el evento de clic, y no desea manejarlo, cuando se hace clic en la entrada, puede simplemente pasar
event.target
a su controlador y verificar si el controlador debe ejecutarse en función de propiedades del objetivo.Por ejemplo, puede comprobarlo
if (target.localName === "input") { return}
.Por tanto, es una forma de "evitar" la ejecución del controlador.
fuente
¡La nueva forma de hacer esto es mucho más simple y le ahorrará algo de tiempo! Simplemente pase el evento al controlador de clic original y llame
preventDefault();
.fuente