React onClick and preventDefault() link refresh/redirect?

前端 未结 13 767
生来不讨喜
生来不讨喜 2020-11-30 06:04

I\'m rendering a link with react:

render: ->
  `upvote`

Then, above I hav

相关标签:
13条回答
  • 2020-11-30 06:45

    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!

    0 讨论(0)
  • 2020-11-30 06:46

    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();
    
    0 讨论(0)
  • 2020-11-30 06:46

    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

    0 讨论(0)
  • 2020-11-30 06:48

    If you use checkbox

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

    stopPropagation and stopImmediatePropagation won't be working.

    Because you must using onClick={this.checkboxHandler}

    0 讨论(0)
  • 2020-11-30 06:49

    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>);
    {
    
    0 讨论(0)
  • 2020-11-30 06:49

    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
    
    }
    
    0 讨论(0)
提交回复
热议问题