Aqui está um componente básico. Tanto o <ul>
e <li>
têm funções onClick. Quero apenas o onClick no <li>
para disparar, não o <ul>
. Como posso conseguir isso?
Eu brinquei com e.preventDefault (), e.stopPropagation (), sem sucesso.
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
fonte
fonte
Respostas:
Eu tive o mesmo problema. Eu encontrei stopPropagation fez trabalho. Eu dividiria o item da lista em um componente separado, assim:
fonte
this.props.handleClick()
noListItem
componentethis.props.click
?<Link>
O React usa delegação de evento com um único ouvinte de evento no documento para eventos que borbulham, como 'clique' neste exemplo, o que significa que não é possível interromper a propagação; o evento real já se propagou no momento em que você interage com ele no React. stopPropagation no evento sintético do React é possível porque o React lida com a propagação de eventos sintéticos internamente.
fonte
document.addEventListener('click')
combinado comonClick
Na ordem dos eventos DOM: CAPTURING vs BUBBLING
Existem dois estágios de propagação dos eventos. Estes são chamados de "captura" e "borbulhamento" .
O estágio de captura acontece primeiro e, em seguida, é seguido pelo estágio de borbulhamento. Quando você registra um evento usando a API DOM regular, os eventos farão parte do estágio de bolha por padrão, mas isso pode ser especificado na criação do evento
No React, eventos de bolha também são usados por padrão.
Vamos dar uma olhada dentro de nosso callback handleClick (React):
Uma alternativa que não vi mencionada aqui
Se você chamar e.preventDefault () em todos os seus eventos, poderá verificar se um evento já foi tratado e evitar que ele seja tratado novamente:
Para saber a diferença entre eventos sintéticos e eventos nativos, consulte a documentação do React: https://reactjs.org/docs/events.html
fonte
Isso não é 100% ideal, mas se for muito chato passar para
props
crianças -> moda infantil ou criar umContext.Provider
/Context.Consumer
apenas para essa finalidade), e você está lidando com outra biblioteca que tem seu próprio manipulador que executa antes do seu, você também pode tentar:Pelo que entendi, o
event.persist
método evita que um objeto seja imediatamente jogado de volta naSyntheticEvent
piscina do React . Então, por causa disso, oevent
passado no React não existe no momento em que você o alcança! Isso acontece com os netos devido à maneira como o React trata as coisas internamente, verificando primeiro o pai em busca deSyntheticEvent
manipuladores (especialmente se o pai tiver um retorno de chamada).Contanto que você não esteja chamando
persist
algo que criaria uma memória significativa para continuar criando eventos comoonMouseMove
(e você não está criando algum tipo de jogo Cookie Clicker como os Cookies da Vovó), deve estar perfeitamente bem!Observe também: ao ler seu GitHub ocasionalmente, devemos manter nossos olhos abertos para versões futuras do React, pois eles podem eventualmente resolver alguns dos problemas com isso, pois parecem estar indo para fazer o código React dobrável em um compilador / transpilador.
fonte
Tive problemas para
event.stopPropagation()
trabalhar. Se você também fizer isso, tente movê-lo para o topo da sua função de manipulador de cliques, era o que eu precisava fazer para impedir que o evento borbulhasse. Função de exemplo:fonte
Você pode evitar o borbulhamento do evento verificando o destino do evento.
Por exemplo, se você tiver uma entrada aninhada no elemento div onde tem o manipulador para o evento click e não quiser manipulá-lo, quando a entrada for clicada, você pode simplesmente passar
event.target
para o seu manipulador e verificar se o manipulador deve ser executado com base em propriedades do alvo.Por exemplo, você pode verificar
if (target.localName === "input") { return}
.Portanto, é uma maneira de "evitar" a execução do manipulador
fonte
A nova maneira de fazer isso é muito mais simples e você vai economizar algum tempo! Basta passar o evento para o manipulador de cliques original e chamar
preventDefault();
.fonte