23

I'm trying to update my component state when you click on an anchor tag inside the render method. I've tried binding inside the constructor, but still the console.log isn't being called. Below is my code. Please help. This is holding me back from progressing lol.

This is modified code based on my previous question here on stackoverflow.

const React = require('react');


class Navbar extends React.Component {
  constructor(...props) {
    super(...props);
    this.setActiveTab = this.setActiveTab.bind(this)
    this.state = {
      currentPage: "/"
    }
  }

  setActiveTab(e) {
    console.log(e.target)
    this.setState({
      currentPage: e.target.href 
    })
  }

  render() {
    const { path } = this.props
    let classString = path === this.state.currentPage ? 'nav-item is-tab is-active' : 'nav-item is-tab'

    return (
      <nav className="nav">

        <div className="nav-left">
          <a className="nav-item">
            <h1>CREATORS NEVER DIE</h1>
          </a>
        </div>

        <div className="nav-right nav-menu">
          <a href="/" className={classString} onClick={this.setActiveTab}>
            Home
          </a>
        </div>


      </nav>
    )
  }
}

module.exports = Navbar;
4
  • 3
    you used href='/' that's why, remove href from a or use href='javascript:void(0)' Commented May 31, 2017 at 18:30
  • Your anchor tag has a href. The onClick won't fire because the link is taking you to another page.
    – glhrmv
    Commented May 31, 2017 at 18:30
  • @MayankShukla I removed the href and still nothing showing in console
    – Dileet
    Commented May 31, 2017 at 18:33
  • @dileet.. did u got answer to ur question? what did u do to make it work?
    – kumar
    Commented Feb 18, 2020 at 19:46

4 Answers 4

29

You need e.preventDefault() in the click handler.

It's firing but the default behavior of an anchor is to refresh the page, so it's just rerendering immediately.

4
  • 1
    Where exactly are we supposed to call this? My onClick handler doesn't have any reference to e or anything like that. Commented Sep 5, 2019 at 21:37
  • 4
    handleClick = (e) => { e.preventDefault(); console.log('The link was clicked.'); };
    – 44kksharma
    Commented Apr 28, 2020 at 7:05
  • <a href="#" className={classString} onClick={this.setActiveTab}>
    – 44kksharma
    Commented Apr 28, 2020 at 7:06
  • @44kksharma it will push extra # in URL. Use href='javascript:void(0)' instead of href="#" Commented May 7, 2020 at 8:51
9

Check the working snippet, both the ways are working, either remove the href or use href='javascript:void(0)' console is printing the proper value on click of Home:

class Navbar extends React.Component {
    constructor() {
      super();
      this.setActiveTab = this.setActiveTab.bind(this)
      this.state = {
         currentPage: '',
      }
  }

  setActiveTab(e) {
      console.log(e.target);
  }

  render() {
      return (
         <div className="nav-right nav-menu">
           
            <a onClick={this.setActiveTab}>
               Home1
            </a>

            <br/>

            <a href='javascript:void(0)' onClick={this.setActiveTab}>
              Home2
            </a>
          
         </div>
      )
   }
}

ReactDOM.render(<Navbar/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id='app'/>

2
  • Hmm could this have something to with me rendering react on the server... Because I see it works, but it's not working on my end.
    – Dileet
    Commented May 31, 2017 at 18:40
  • sorry, don't have idea about serverside rendering. Commented May 31, 2017 at 18:46
4

Researching the issue it appears you need to prevent the default of the anchor tag. Also if you create an arrow function you are able to handle the this.

Prevent default info can be found on React docs here

Hope this helps.

 const React = require("react");

class Navbar extends React.Component {
    constructor(...props) {
        super(...props);
        this.setActiveTab = this.setActiveTab.bind(this);
        this.state = {
            currentPage: "/",
        };
    }

    setActiveTab = (e) => {
        e.preventDefault();
        console.log(e.target);
        this.setState({
            currentPage: e.target.href,
        });
    }

    render() {
        const { path } = this.props;
        let classString =
            path === this.state.currentPage ? "nav-item is-tab is-active" : "nav-item is-tab";

        return (
            <nav className="nav">
                <div className="nav-left">
                    <a className="nav-item">
                        <h1>CREATORS NEVER DIE</h1>
                    </a>
                </div>

                <div className="nav-right nav-menu">
                    <a href="/" className={classString} onClick={this.setActiveTab}>
                        Home
                    </a>
                </div>
            </nav>
        );
    }
}

module.exports = Navbar;
0
Alternatively you can have Button on grid column instead of link to perform activity.

1) Button way : 
<Button
        variant="contained"
        color="primary"
        onClick={(event) => {
          this.handleCellClick(event, cellValues);
        }}
      >
        ...View Full List
      </Button>

2) Link to work
<a href="#" onClick={this.setActiveTab}>
      ...View Full List
                    </a>
  setActiveTab = (e) => {
    e.preventDefault();
    console.log(e.target);
}

Not the answer you're looking for? Browse other questions tagged or ask your own question.