118

I'm rendering a link with react:

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

Then, above I have the upvote function:

upvote: -> // do stuff (ajax) 

Before link I had span in that place but I need to switch to link and here's the trouble - every time I click on .upvotes the page gets refreshed, what I've tried so far:

event.preventDefault() - not working.

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

event.stopPropagation() - not working.

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

return false - not working.

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

I've also tried all of the above using jQuery in my index.html, but nothing seems to work. What should I do here and what I'm doing wrong? I've checked event.type and it's click so I guess I should be able to avoid redirect somehow?

Excuse me, I'm a rookie when it comes to React.

Thank you!

8
  • 1
    are you trying to use es2015 syntax for the functions? Commented Mar 30, 2016 at 18:31
  • What sort of components are you creating? Stateless? createClass? Commented Mar 30, 2016 at 18:52
  • Can you confirm that onClick is actually hitting upvote ? This might be a context issue. Commented Mar 30, 2016 at 21:24
  • 2
    Use preventDefault Commented Aug 4, 2017 at 9:31
  • 1
    e.PreventDefault() alone worked for me (React 16.0.0-beta5) Commented Aug 14, 2017 at 6:40

16 Answers 16

106

React events are actually Synthetic Events, not Native Events. As it is written here:

Event delegation: React doesn't actually attach event handlers to the nodes themselves. When React starts up, it starts listening for all events at the top level using a single event listener. When a component is mounted or unmounted, the event handlers are simply added or removed from an internal mapping. When an event occurs, React knows how to dispatch it using this mapping. When there are no event handlers left in the mapping, React's event handlers are simple no-ops.

Try to use Use Event.stopImmediatePropagation:

upvote: (e) -> e.stopPropagation(); e.nativeEvent.stopImmediatePropagation(); 
Sign up to request clarification or add additional context in comments.

1 Comment

Event.stopPropagation in 2021.
94

A full version of the solution will be wrapping the method upvotes inside onClick, passing e and use native 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>); { 

5 Comments

Is there a difference between e.preventDefault(); being in the beggining or the end of the function? Where it makes more sense to be placed?
I think it is better to use it in the beginning
It's bad practices, please read about an arrow functions and .bind(this) for bin context in a react app. For example: medium.freecodecamp.org/…
except this is just creating a function to pass the argument. If you're using react and ES6 already, you don't need the scoped function. And you could just as easily accomplish that by binding it with this in the constructor.
Beware that if you trigger a rendering (e.g. by changing the state) before having called the e.preventDefault() it will have no effect. So better have it as first statement of the event handler.
16

try bind(this) so your code looks like below --

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

or if you are writing in es6 react component in constructor you could do this

constructor(props){ super(props); this.upvote = this.upvote.bind(this); } upvote(e){ // function upvote e.preventDefault(); return false } 

1 Comment

This makes no difference. You're getting upvotes because people have this in their event handler and have a totally different issue.
10

In a context like this

function ActionLink() { function handleClick(e) { e.preventDefault(); console.log('The link was clicked.'); } return ( <a href="#" onClick={handleClick}> Click me </a> ); } 

As you can see, you have to call preventDefault() explicitly. I think that this docs, could be helpful.

1 Comment

It works actally! V17.0.2.
9

render: -> <a className="upvotes" onClick={(e) => {this.upvote(e); }}>upvote</a>

2 Comments

It's bad practices, please read about an arrow functions and .bind(this) for bin context in a react app. For example: medium.freecodecamp.org/…
createReactClass or Autobinding or use npm package 'auto-bind'
3

A nice and simple option that worked for me was:

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

3 Comments

this is sooo underrated. i want to kiss you if you don't mind. you saved me from a lot of things sir. for the form element action="javascript: false" is also working.
@OzgurBagci Using the method above will throw warnings in React in more recent versions. It may work now, but probably won't work longer term. Probably best to find an alternate method, especially if using a more current version of React.
This solution gives the following warning (as mentioned by David): react-dom.development.js:86 Warning: A future version of React will block javascript: URLs as a security precaution. Use event handlers instead if you can. If you need to generate unsafe HTML try using dangerouslySetInnerHTML instead. React was passed "javascript: false".
2

The Gist I found and works for me:

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

Credit for srph https://gist.github.com/srph/020b5c02dd489f30bfc59138b7c39b53

1 Comment

May I suggest not to use onClick as a passed prop function name, but something like handleClick instead? It's confusing, other less experienced developers might think it's the actual attached event to the component, while it's not. Also, with this, you are creating a new function each time the component re-renders, even if it's receiving the same props. It's considered a bad practice.
2

I didn't find any of the mentioned options to be correct or work for me when I came to this page. They did give me ideas to test things out and I found that this worked for me.

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

Comments

1

This is because those handlers do not preserve scope. From react documentation: react documentation

Check the "no autobinding" section. You should write the handler like: onClick = () => {}

Comments

1
<button className="upvotes" onClick={this.upvote}>upvote</button> 

HTML Button should be used if you want to execute Javascript script without navigating to a new page.

If using a href without a proper address, eslint would throw:

The href attribute requires a valid value to be accessible. Provide a valid, navigable address as the href value. If you cannot provide a valid href, but still need the element to resemble a link, use a button and change it with appropriate styles.

jsx-a11y/anchor-is-valid suggests:

<a href="javascript:void(0)" onClick={foo}>Perform action</a> <a href="#" onClick={foo}>Perform action</a> <a onClick={foo}>Perform action</a> 

All these anchor implementations indicate that the element is only used to execute JavaScript code. All the above should be replaced with:

<button onClick={foo}>Perform action</button> 

Related:

Comments

0

If you are using React Router, I'd suggest looking into the react-router-bootstrap library which has a handy component LinkContainer. This component prevents default page reload so you don't have to deal with the event.

In your case it could look something like:

import { LinkContainer } from 'react-router-bootstrap'; <LinkContainer to={givePathHere}> <span className="upvotes" onClick={this.upvote}>upvote</span> </LinkContainer> 

Comments

0

I've had some troubles with anchor tags and preventDefault in the past and I always forget what I'm doing wrong, so here's what I figured out.

The problem I often have is that I try to access the component's attributes by destructuring them directly as with other React components. This will not work, the page will reload, even with e.preventDefault():

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

It seems the destructuring causes an error (Cannot read property 'href' of undefined) that is not displayed to the console, probably due to the page complete reload. Since the function is in error, the preventDefault doesn't get called. If the href is #, the error is displayed properly since there's no actual reload.

I understand now that I can only access attributes as a second handler argument on custom React components, not on native HTML tags. So of course, to access an HTML tag attribute in an event, this would be the way:

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

I hope this helps other people like me puzzled by not shown errors!

Comments

0

just like pure js do preventdefault : in class you should like this create a handler method :

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

Comments

0
function ActionLink() { const handleClick = (e) => { e.preventDefault(); console.log('The link was clicked.'); } return ( <a href="#" onClick={handleClick}> Click me </a> ); } 

Call e.preventDefault() + make sure the callback function is arrow function.

Comments

-1

If you use checkbox

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

stopPropagation and stopImmediatePropagation won't be working.

Because you must using onClick={this.checkboxHandler}

Comments

-2

You should pass the event object when you call the method. e.g

const handleOnSubmit = (e) => { console.log("in submit"); e.preventDefault(); }; 

you should call this like

<form onSubmit={(e) => handleOnSubmit(e)}> 

where you should pass e as the event object

1 Comment

- "You should pass the event object when you call the method" he is...

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.