3

I have this issue where when i switch from one component to other using react router my google recaptcha div stops displaying. My component with google recaptcha

   class Contact extends React.Component{
  constructor(props){
    super(props);
    document.title = "Contact";
  }
  errorHandle(err){
    let loc = document.getElementById("err-" + err);
    loc.className = "error-live";
    setTimeout(() =>{
      loc.className = "error";
    },errSpeed);
  }
  sendMail(e){
    e.preventDefault();
    let message = document.getElementById("message").value,
        name = document.getElementById("name").value,
        email = document.getElementById("email").value,
        captcha = grecaptcha.getResponse();
    if(email.length < 4 || email.length < 4 || name.length < 4){
      this.errorHandle("short");
      return;
    }else if(email.indexOf("@") === -1){
      this.errorHandle("email");//make error
      return;
    }else if(captcha.length === 0){
      this.errorHandle("recaptcha");//make error
      return;
    }
    sa
      .post("./back-end/contact.php")
      .send({name,email,message,captcha})
      .type("application/x-www-form-urlencoded")
      .end(function(err,res){
        res = res.text;
        if(res.search("sent") > 0){
          dbId("contact-done").style.display = "block";
          dbId("contact").style.opacity = 0;
          dbId("contact-done").style.opacity = 1;
          setTimeout(() =>{
            window.location.replace(window.location.href.replace("contact",""));
          },errSpeed);
        }else if(res === "failToSend")
          alert("Failed to send the message please try again");
      })

  }
  render(){
    return(
      <div className = "contact">
        <div id = "contact-done"><p>Thank you for contacting us</p></div>
        <form id = "contact" className="pure-form pure-form-stacked">
          <fieldset>
            <legend>Contact me</legend>

            <label>Name</label>
            <input id="name" type="text" placeholder="Name"></input>

            <label>Email</label>
            <input id="email" type="email" placeholder="Email"></input>

            <label>Message</label>
            <textarea id = "message"></textarea>

            <div id = "recaptcha-contact" className="g-recaptcha" data-sitekey="myKeyHere"></div>

            <div id = "err-email" className = "error">Invalid Email adress</div>
            <div id = "err-recaptcha" className = "error">Please fill in google recaptcha</div>
            <div id = "err-short" className = "error">Each field has to be atleast 4 characters long</div>

            <button onClick = {this.sendMail.bind(this)} className="pure-button pure-button-primary">Send</button>
        </fieldset>
      </form>
    </div>
    );
  }
}

If I load the http://localhost/contact it shows up,however as soonas I change path to lets say http://localhost/articles and switch back it disappears.What could be the cause?

Thank you for your time.

August
  • 1,722
  • 5
  • 20
  • 37

2 Answers2

1

I searched for a while and could not find the solution to the problem,what I ended up doing is re rendering the recaptcha each time component is visited :

componentDidMount(){
  setTimeout(() =>{
    window.grecaptcha.render('recaptcha-contact', {
       sitekey: "key",
       callback: function(resp){}
    });
  },300);
}

Timeout is there since grecaptcha would be undefined.

August
  • 1,722
  • 5
  • 20
  • 37
0

reference to this link https://github.com/ReactTraining/react-router/issues/3256

You should load the google captcha js file every time the component get loaded.

it can simply done by using loadJs module.

Install the module with npm install loadjs and you just need to add var loadjs = require('loadjs'); loadjs('https://www.google.com/recaptcha/api.js?hl=fa'); to your component.

Also you don`t even need to add the js file to your html codes!

Silent-B
  • 35
  • 1
  • 5