JAbrams
JAbrams

Reputation: 325

React <a> tag and button onClick propagation

I want to create a React component with a render method that has an <a> tag that wraps an entire "box", if you will, which redirects to another page when clicked. Within said box there is a <button> that can be clicked that activates an event that changes state. What I want to be able to do is click the <button> and trigger the event without the redirect from the <a> tag occurring.

Tried some ideas with stopPropagation() but no luck :/ I don't want to move the button outside of the <a> tag either so not sure where to go from here.

It seems like it should be something simple but I just can't figure it out. Thanks!

the render method looks like this:

render(){
 return(
  <div>
   <a href="http://www.google.com"> 
    <div className="box">

     <h2 className="title">Random Title</h2>

     <button onClick={this.handleClick}> Like </button>

    </div>  
   </a>
  </div> 
 )
}

handleClick() would look something like this:

handleClick = () => {
  if (this.state.liked) {
  console.log("disliking")
} else {
  console.log("liking")
}

this.setState({ liked: !this.state.liked})
}

Upvotes: 6

Views: 44486

Answers (3)

hawkeyegold
hawkeyegold

Reputation: 129

One way this can be done is by setting a reference to the anchor element, then using the button elements onMouseEnter and onMouseLeave to programatically change the anchor elements href property whenever the user moves the mouse over the Like button.

class Test extends React.Component {

  constructor(props){
    super(props)
    this.state={ likes:0 }
    this.anchorElement=null;
  }

  enter = () => { this.anchorElement.href='javascript:;'; }
  leave = () => { this.anchorElement.href='http://www.google.com'; }
  handleClick = () => { this.setState({ likes: ++this.state.likes}); }

  render() {
    return (
      <div>
        <div>{'Likes:'+this.state.likes}</div>
        <a href="http://www.google.com" ref={(el) => { if (el) { this.anchorElement = el; } }}>
          <div>
            <h2 className="title">Random Title</h2>
            <button onClick={this.handleClick} onMouseEnter={this.enter} onMouseLeave={this.leave}> Like </button>
          </div>
        </a>
      </div>
    );
  }
}

See it in action: Working fiddle

In the fiddle you will note the link is activating, but is not going anywhere because it is effectively "turned off" while the button is under the mouse. If you want to get rid of the appearance of activation on the link, a little more manipulation of the anchor element is needed, or simply set the a:active css property to the same color as the base/active color.

Personally, I would avoid the scenario if possible, but that's just good advice, something that more folks around here should learn is not the same thing as an answer.

Upvotes: 1

Rabi
Rabi

Reputation: 2220

you can achieve this with a simple trick. see what I did -

  1. replace the anchor with a div and place a click handler
  2. add a flag (clicked) with in the component and ignore in div click handler if it's a button click
  3. reset the flag

update - check out this js fiddle : https://jsfiddle.net/rabinarayanb/pvx2n3x3/

note - I have used es5 syntax. you can convert to es6

(function() {   
    var BoxSetup = React.createClass({


        clicked : "",

        getInitialState : function () {
            return { clickCount : 0};
        },

        handleDivClick : function (event) {
            if (this.clicked !== "Button") {
                window.location.href = "http://www.google.com";
            }

            // reset
            this.clicked = "";
        },

        handleButtonClick : function (event) {
           this.clicked = "Button"
           this.setState({
                clickCount : ++this.state.clickCount
           });
        },

        render : function () {

            return (
            <div>
                <div onClick={this.handleDivClick} style={ { }}>
                    <div style={ { width : "100px", height : "100px", border : "1px solid red" } }>
                        <h2 className="title">{ this.state.clickCount }</h2>
                        <button onClick={this.handleButtonClick}> Like </button>
                    </div>
                </div>
            </div> 
            );
        }
    });

    var element = React.createElement(BoxSetup, { title : "Hello" });

    ReactDOM.render(element, document.getElementById("app"));    
})();

Upvotes: 2

Sienile
Sienile

Reputation: 186

What you are wanting to do does not seem possible. Once the user clicks on the <a> enclosed content they will be redirected to the linked content, in your case: http://www.google.com If you want to execute your function then follow the link you must remove the <a> tag and put window.location = "http://www.google.com"; at the end of your function.

Upvotes: 1

Related Questions