web-dev-qa-db-fra.com

Réagissez onClick et preventDefault () link refresh/redirect?

Je suis en train de rendre un lien avec react:

render: ->
  `<a className="upvotes" onClick={this.upvote}>upvote</a>`

Ensuite, ci-dessus, j'ai la fonction vote positif:

upvote: ->
  // do stuff (ajax)

Avant le lien, je devais passer à cet endroit mais je dois changer de lien et voici le problème - chaque fois que je clique sur .upvotes, la page est actualisée, ce que j'ai déjà essayé:

event.preventDefault () - ne fonctionne pas.

upvote: (e) ->
  e.preventDefault()
  // do stuff (ajax)

event.stopPropagation () - ne fonctionne pas.

upvote: (e) ->
  e.stopPropagation()
  // do stuff (ajax)

return false - ne fonctionne pas.

upvote: (e) ->
  // do stuff (ajax)
  return false

J'ai également essayé tout ce qui précède en utilisant jQuery dans mon index.html, mais rien ne semble fonctionner. Que dois-je faire ici et ce que je fais mal? J'ai vérifié event.type et c'est click alors je suppose que je devrais être capable d'éviter la redirection d'une manière ou d'une autre?

Excusez-moi, je suis une recrue en ce qui concerne React.

Je vous remercie!

48
Wordpressor

Les événements React sont en fait des événements synthétiques et non des événements natifs. Comme il est écrit ici :

Délégation d'événements: React n'attache pas réellement de gestionnaires d'événements aux nœuds eux-mêmes. Lorsque React démarre, il commence à écouter tous les événements du niveau supérieur à l'aide d'un seul écouteur d'événements. Lorsqu'un composant est monté ou démonté, les gestionnaires d'événements sont simplement ajoutés ou supprimés d'un mappage interne. Lorsqu'un événement se produit, React sait comment le distribuer à l'aide de ce mappage. Lorsqu'il ne reste plus aucun gestionnaire d'événement dans le mappage, les gestionnaires d'événement de React sont de simples opérations sans intervention.

Essayez d'utiliser Utiliser Event.stopImmediatePropagation:

upvote: (e) ->
  e.stopPropagation();
  e.nativeEvent.stopImmediatePropagation();
37
Alexandr Lazarev

Une version complète de la solution encapsulera les votes positifs de la méthode dans onClick, en passant e et en utilisant e.preventDefault () natif;

upvotes = (e, arg1, arg2, arg3 ) => {
    e.preventDefault();
    //do something...
}

render(){
    return (<a type="simpleQuery" onClick={ e => this.upvotes(e, arg1, arg2, arg3) }>
      upvote
    </a>);
{
42
Roman

essayez bind (this) pour que votre code ressemble à celui ci-dessous -

 <a className="upvotes" onClick={this.upvote.bind(this)}>upvote</a>

ou si vous écrivez en es6 réagir composant dans le constructeur, vous pouvez le faire

constructor(props){
   super(props);
   this.upvote = this.upvote.bind(this);
}

upvote(e){   // function upvote
   e.preventDefault();
   return false

}
15
deepak prakash

Le Gist j'ai trouvé et travaille pour moi:

const DummyLink = ({onClick, children, props}) => (
    <a href="#" onClick={evt => {
        evt.preventDefault();
        onClick && onClick();
    }} {...props}>
        {children}
    </a>
);

Crédit pour srph https://Gist.github.com/srph/020b5c02dd489f30bfc59138b7c39b53

1

J'ai eu quelques problèmes avec les balises anchor et preventDefault dans le passé et j'oublie toujours ce que je fais mal, alors voici ce que j'ai découvert.

Le problème que j’ai souvent, c’est que j’essaie d’accéder aux attributs du composant en les déstructurant directement comme avec d’autres composants React. Cela ne fonctionnera pas, la page se rechargera , même avec e.preventDefault():

function (e, { href }) {
  e.preventDefault();
  // Do something with href
}
...
<a href="/foobar" onClick={clickHndl}>Go to Foobar</a>

Il semble que la déstructuration provoque une erreur (Cannot read property 'href' of undefined) qui ne s'affiche pas sur la console, probablement en raison du rechargement complet de la page. Puisque la fonction est en erreur, la preventDefault n'est pas appelée. Si href est #, l'erreur est affichée correctement car il n'y a pas de rechargement réel.

Je comprends maintenant que je ne peux accéder aux attributs que comme argument de second gestionnaire sur les composants React personnalisés, et non sur les balises HTML natives . Alors bien sûr, pour accéder à un attribut de balise HTML dans un événement, ceci serait le chemin suivant:

function (e) {
  e.preventDefault();
  const { href } = e.target;
  // Do something with href
}
...
<a href="/foobar" onClick={clickHndl}>Go to Foobar</a>

J'espère que cela aide d'autres personnes comme moi perplexes devant des erreurs non montrées!

0
DSav

Je n'ai trouvé aucune des options mentionnées correcte ou qui ne fonctionnait pour moi lorsque je suis arrivé sur cette page. Ils m'ont donné des idées pour tester les choses et j'ai trouvé que cela fonctionnait pour moi.

dontGoToLink(e) {
  e.preventDefault();
 }

render() {
  return (<a href="test.com" onClick={this.dontGoToLink} />});
}
0
Iwnnay

Dans un contexte comme celui-ci

function ActionLink() {
  function handleClick(e) {
    e.preventDefault();
    console.log('The link was clicked.');
  }

  return (
    <a href="#" onClick={handleClick}>
      Click me
    </a>
  );
}

Comme vous pouvez le constater, vous devez appeler explicitement preventDefault () . Je pense que this docs pourrait être utile.

0
Fabien Sartori

Une option simple et agréable qui a fonctionné pour moi était:

<a href="javascript: false" onClick={this.handlerName}>Click Me</a>
0
David

Si vous utilisez React Router, je vous conseillerais de consulter la bibliothèque react-router-bootstrap, qui contient un composant pratique, LinkContainer. Ce composant empêche le rechargement de page par défaut afin que vous n'ayez pas à gérer l'événement.

Dans votre cas, cela pourrait ressembler à quelque chose comme:

import { LinkContainer } from 'react-router-bootstrap';

<LinkContainer to={givePathHere}>
    <span className="upvotes" onClick={this.upvote}>upvote</span>
</LinkContainer>
0
iggirex

En effet, ces gestionnaires ne préservent pas la portée. De réaction documentation: réaction documentation

Vérifiez la section "pas de liaison automatique". Vous devriez écrire le gestionnaire comme ceci: onClick = () => {}

0
viktor

Si vous utilisez la case à cocher

<input 
    type='checkbox'
    onChange={this.checkboxHandler}
/>

stopPropagation et stopImmediatePropagation ne fonctionnera pas.

Parce que vous devez utiliser onClick = {this.checkboxHandler}

aucune de ces méthodes ne fonctionnait pour moi, alors je viens de résoudre ce problème avec CSS:

.upvotes:before {
   content:"";
   float: left;
   width: 100%;
   height: 100%;
   position: absolute;
   left: 0;
   top: 0;
}
0
Suat Ağgez