Redirect happens before onClick() on REACT { Link }

Viewed 2421

Redirect happens before onClick() on REACT { Link }

Hello. I'm trying the whole day to play a sound onClick Button Event. It works when I remove the Link (URL), but with the Link, the page goes to the new URL without firing the onClick event. I already tried like this: onClick={() => this.playAudioHandler}. I really appreciate if someone can fix my code in order to fire the “playAudioHandler” before going to the new URL.

This is my actual code:

import React, { Component } from "react";
import { Link } from "react-router-dom";

import classes from "./Button.module.css";
import clickSound from "../assets/click.mp3";

class Button extends Component {
  playAudioHandler = (event) => {
    const audioEl = document.getElementsByClassName("audio-element")[0];
    audioEl.play();
    // event.preventDefault();
  };
  render() {
    return (
      <>
        <audio className="audio-element">
          <source src={clickSound}></source>
        </audio>
        <Link to={this.props.linkToGo}>
          <button
            type="submit"
            onClick={this.playAudioHandler}
            className={[classes.Button, classes[this.props.btnType]].join(" ")}
            // join() to transform the array in a string
          >
            {this.props.children}
          </button>
        </Link>
      </>
    );
  }
}

export default Button;
2 Answers

How about trying setting a state that defines where to redirect and setting that state inClick the button:

import React, { Component } from "react";
import { Redirect } from "react-router-dom";

import classes from "./Button.module.css";
import clickSound from "../assets/click.mp3";

class Button extends Component {
    constructor(super) {
        super(props);
        this.state = {
            redirect: null
        }
 }
 playAudioHandler = (event) => {
      const audioEl = 
   document.getElementsByClassName("audio-element")[0];
    audioEl.play();
    // event.preventDefault()
     this.setState({ redirect: this.props.linkToGo })
 };
 render() {
      if (this.state.redirect) {
       return <Redirect to={redirect} />
   }
   return (
  <>
    <audio className="audio-element">
      <source src={clickSound}></source>
    </audio>

      <button
        type="submit"
        onClick={ this.playAudioHandler}
        className={[classes.Button, 
        classes[this.props.btnType]].join(" ")}
        // join() to transform the array in a string
      >
           {this.props.children}
           </button>

           </>
        );
    }
}

export default Button;

Let me know if it works!

Link is firing each click because is the way it works. In your case, button is wrapped by Link, so Link gets fired.
An easy way to achieve that is to avoid using Link and, since looks like your are using react-router-dom.

<button
   type="submit"
   onClick={this.playAudioHandler}
   className={[classes.Button, 
   classes[this.props.btnType]].join(" ")}
>
   {this.props.children}
</button>

And your handler will redirect after sound was played:

playAudioHandler = (event) => {
    event.preventDefault();
    const audioEl = document.getElementsByClassName("audio-element")[0];
    audioEl.play();

    const waitSecs = 3000 // 3 secs
    setTimeout(() => {
      history.push('/url');
      OR
      window.location.href = 'url'
    }, waitSecs);
  };
Related