onClickに反応してPreventDefault()リンクを更新/リダイレクトしますか?


87

私はreactでリンクをレンダリングしています:

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

次に、上記に賛成票機能があります。

upvote: ->
  // do stuff (ajax)

リンクの前に私はその場所にスパンしていましたが、リンクに切り替える必要があり、ここに問題があります-.upvotesページをクリックするたびに更新され、これまでに試したことは次のとおりです。

event.preventDefault()-機能していません。

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

event.stopPropagation()-機能していません。

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

falseを返します-機能しません。

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

index.htmlでjQueryを使用して上記のすべてを試しましたが、何も機能しないようです。ここで何をすべきで、何が間違っているのですか?event.typeを確認しましたが、clickどういうわけかリダイレクトを回避できるはずです。

すみません、Reactに関しては私は新人です。

ありがとうございました!


1
関数にes2015構文を使用しようとしていますか?
erichardson30 2016年

どのようなコンポーネントを作成していますか?ステートレス?createClass?
markthethomas 2016年

onClickが実際にヒットしていることを確認できますupvoteか?これはコンテキストの問題である可能性があります。
thangngoc89 2016年

1
使用preventDefault
onmyway133 2017

1
e.PreventDefault()だけでうまくいきました(React 16.0.0-beta5)
felix-b

回答:


70

Reactイベントは実際には合成イベントであり、ネイティブイベントではありません。ここに書かれているように

イベントの委任:Reactは、実際にはイベントハンドラーをノード自体にアタッチしません。Reactが起動すると、単一のイベントリスナーを使用してトップレベルですべてのイベントのリッスンを開始します。コンポーネントがマウントまたはマウント解除されると、イベントハンドラーは内部マッピングに追加または削除されます。イベントが発生すると、Reactはこのマッピングを使用してイベントをディスパッチする方法を知っています。マッピングにイベントハンドラーが残っていない場合、Reactのイベントハンドラーは単純な操作なしです。

使用してみてくださいEvent.stopImmediatePropagation

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

74

ソリューションのフルバージョンは、onClick内でメソッドの賛成票をラップし、eを渡し、ネイティブのe.preventDefault()を使用します。

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

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

e.preventDefault();に違いはありますか?関数の開始または終了にありますか?配置する方が理にかなっている場所はどこですか?
Sartheris Stormhammer 2018

最初に使用する方が良いと思います
ローマ

悪い習慣.bind(this)です。矢印関数とreactアプリのビンコンテキストについて読んでください。例:medium.freecodecamp.org/…–
ジョイフル

ただし、これは引数を渡す関数を作成するだけです。すでにreactとES6を使用している場合は、スコープ関数は必要ありません。そして、コンストラクターでこれとバインドすることで、同じように簡単にそれを達成できます。
Iwnnay 2018

e.preventDefault()を呼び出す前に(状態を変更するなどして)レンダリングをトリガーしても、効果がないことに注意してください。したがって、イベントハンドラーの最初のステートメントとして使用することをお勧めします。
ThimAnneessens18年

16

bind(this)を試して、コードが次のようになるようにします-

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

または、コンストラクターでes6 reactコンポーネントを記述している場合は、これを行うことができます

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

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

}

9
これは違いはありません。人々がthisイベントハンドラーにいて、まったく異なる問題を抱えているため、あなたは賛成票を獲得しています。
Dimitar Nestorov 2018

8

レンダリング:-> <a className="upvotes" onClick={(e) => {this.upvote(e); }}>upvote</a>


1
悪い習慣.bind(this)です。矢印関数とreactアプリのビンコンテキストについて読んでください。例:medium.freecodecamp.org/…–
ジョイフル

createReactClassまたは自動バインドまたは使用NPMパッケージ「自動バインド」
xjinjin

7

このような状況では

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

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

ご覧のとおり、preventDefault()を明示的に呼び出す必要があります。このドキュメントが役立つと思います。


2

私のために働いた素晴らしくて単純なオプションは次のとおりでした:

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

これはすっごく過小評価されています。よろしければキスしたいです。あなたは私を多くのことから救ってくれました。フォーム要素action="javascript: false"も機能しています。
OzgurBagci

1
@OzgurBagci上記の方法を使用すると、最新バージョンのReactで警告がスローされます。今は機能するかもしれませんが、おそらく長期的には機能しないでしょう。特に最新バージョンのReactを使用している場合は、別の方法を見つけるのがおそらく最善です。
デビッド

1

これは、これらのハンドラーがスコープを保持しないためです。反応ドキュメントから:反応ドキュメント

「自動バインドなし」セクションを確認してください。次のようにハンドラーを作成する必要があります:onClick =()=> {}


1

私が見つけて私のために働く要点:

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

srphのクレジットhttps://gist.github.com/srph/020b5c02dd489f30bfc59138b7c39b53


1
onClick渡されたprop関数名として使用するのではなく、handleClick代わりに使用することをお勧めしますか?紛らわしいですが、他の経験の浅い開発者は、それがコンポーネントに実際に添付されたイベントであると考えるかもしれませんが、そうではありません。また、これにより、同じ小道具を受け取っている場合でも、コンポーネントが再レンダリングされるたびに新しい関数を作成することになります。それは悪い習慣と考えられています。
elQueFaltaba 2017年

0

チェックボックスを使用する場合

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

stopPropagationstopImmediatePropagationは機能しません。

onClick = {this.checkboxHandler}を使用する必要があるため


0

React Routerを使用している場合は、便利なコンポーネントLinkContainerを備えたreact-router-bootstrapライブラリを調べることをお勧めします。このコンポーネントはデフォルトのページの再読み込みを防ぐため、イベントに対処する必要はありません。

あなたの場合、それは次のようになります。

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

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

0

私はアンカータグでいくつかの問題を抱えていましたがpreventDefault、過去に私が間違っていることをいつも忘れているので、これが私が理解したことです。

私がよく抱える問題は、他のReactコンポーネントと同じように、コンポーネントの属性を直接破壊して、その属性にアクセスしようとすることです。これは機能しません。次の場合でも、ページは再読み込みされますe.preventDefault()

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

Cannot read property 'href' of undefinedおそらくページが完全にリロードされたために、破壊によってコンソールに表示されないエラー()が発生したようです。関数にエラーがあるため、preventDefault呼び出されません。hrefが#の場合、実際のリロードがないため、エラーが正しく表示されます。

ネイティブHTMLタグではなく、カスタムReactコンポーネントの2番目のハンドラー引数としてのみ属性にアクセスできることを理解しました。したがって、もちろん、イベントでHTMLタグ属性にアクセスするには、次のようにします。

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

これが私のような他の人々が表示されていないエラーに戸惑うのに役立つことを願っています!


0

私がこのページに来たとき、私は言及されたオプションのどれもが正しいか私のために働くとは思いませんでした。彼らは私に物事をテストするためのアイデアを与えてくれました、そして私はこれが私のために働いたことを発見しました。

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

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

0

純粋なjsがpreventdefaultを実行するのと同じように:クラスでは、ハンドラーメソッドを作成する必要があります:

handler(event) {
    event.preventDefault();
    console.log(event);
}

-1

これらの方法はどれも私にはうまくいかなかったので、CSSでこれを解決しました:

.upvotes:before {
   content:"";
   float: left;
   width: 100%;
   height: 100%;
   position: absolute;
   left: 0;
   top: 0;
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.