1

Here is my component. whenever i call the event it works fine. But page getting refreshed each time. how to prevent this. I understood that i need to add event.preventDefult but adding that shows error. please show me the correct way to do this:

export class Header extends React.Component {
    
    state:NaviState = {
        show:false
    }

    toggle = ():void =>{
        console.log("h"); //page getting refreshing each click
        this.state = {show:!this.state.show}
    }
    render() {
        return (
            <header>
               <h1><a className="hidden tantum-logo" href="#">Welocome to Tantum website</a></h1>
               <div className="screen"></div>
               <nav className="small">
                   <a className="nav-icon hidden" onClick={this.toggle} href="#">tantum-Menu</a>
               </nav>
            </header>
        )
    }
}
3
  • It seems that my method too not called Commented Dec 20, 2020 at 5:24
  • is that bootstrap? Commented Dec 20, 2020 at 5:28
  • If it's not why cant you use a button with same styles as a link, like bootstrap button link, It will be a valid html too Commented Dec 20, 2020 at 5:34

3 Answers 3

1

You can solve this problem in 2 different ways:

  1. Remove the href attribute - since you want to add a onClick listener you can simply not provide the href value and this should prevent a page reload;

  2. If you want to keep the href (not sure why you would want this) you can do intercept the event in your function:

    toggle = (ev) : any => { // event is implicitly passed to the function
        e.preventDefault();
        e.stopImmediatePropogation(); // might not be needed, would need testing.
        this.state = {show:!this.state.show}
    }
Sign up to request clarification or add additional context in comments.

4 Comments

by the is there any reactjs directive for show hide?
what do you mean by "directive for show hide"?
this is not works for me : <div className={"screen" + (this.state.show ? "show":"hidden")}></div>
what might be going wrong here: is the class name you're expecting screenshow or are you expecting multiple classes applied like screen show (add a space after screen if you're expecting this)? You can also use Template Literals for a cleaner implementation.
0

@thanks ayushya, it works for me:

toggle = (e: { preventDefault: () => void; }):any =>{
  e.preventDefault();
  this.state = {show:!this.state.show};
}

Comments

0

Removing the href may not be ideal for all situations (bots, scrapers, server side rendering) so I am providing a solution that supports both href and preventDefault

/* Solution tested with: 
 *
 * - "typescript": "^4.9.5",
 * - "react": "^18.2.0",
 */

function AnchorWithPreventDefault() {
  function handleClick<E extends Element = HTMLAnchorElement>(
    e: React.MouseEvent<E, MouseEvent>
  ) {
    e.preventDefault(); // block navigation to /somewhere-else
    // do stuff
  }
  return (
    <a href="/somewhere-else" onClick={handleClick}>
      Foo
    </a>
  );
}

Notice we are now referencing both React events and native Event types.

I plucked this technique from the react-router docs:

https://github.com/remix-run/react-router/blob/a0d6c4fe08c7d95e4811bbfa972f529e0a5304d5/packages/react-router-dom/index.tsx#L926

While the react documentation and type system accounts for Form events as 'preventable', it does not appear to consider anchors in the same light, though preventing default behavior is natively supported by browser, but I would guess this is due to the optionality of href

If you don't need generic inputs, here is an alternative solution that is a bit more narrow:

function handleNav(
  e: React.MouseEvent<HTMLAnchorElement, Pick<MouseEvent, 'preventDefault'>>
) {}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.