How do I dynamically change google recaptcha language using React

时间:2019-04-17 02:44:33

标签: javascript reactjs recaptcha

I am using react-google-recaptcha.

I want to dynamically change the recaptcha element whenever I load this component.

Requirements: 1. Had to take new props and change the language 2. On unmount and remount the component should also render new language

  • cleared the global values for google recaptcha on unmount.
  • Forced recaptcha to remount whenever props change
  • Combination of these two

window.recaptchaOptions = { removeOnUnmount: true } does not properly remove the recaptcha.

Expected: The recaptcha will remount and change it's language to the selected language.

Actual: Recaptcha will remount using the same language.

1 个答案:

答案 0 :(得分:0)

Solution:

  1. On mount dynamically import react-google-recaptcha

  2. on unMount delete window.grecaptcha & window.recaptchaOptions

  3. on update combine step 1 & 2

export default class ReCaptchaValidation extends React.Component<Props> {
  static defaultProps = {
    handleChange: null,
    lang: 'en'
  }

  state = {
    Recaptcha: null
  }

  componentDidMount (): void {
    this.importRecaptcha()
  }

  importRecaptcha = async () => {
    const { lang } = this.props
    this.setState({ Recaptcha: null })
    delete window.recaptchaOptions
    delete window.grecaptcha
    window.recaptchaOptions = {
      lang,
      useRecaptchaNet: false,
      removeOnUnmount: false
    }
    const { default: Recaptcha } = await import('react-google-recaptcha')
    this.setState({ Recaptcha })
  }

  componentWillUnmount () {
    delete window.recaptchaOptions
    delete window.grecaptcha
  }

  componentDidUpdate (prevProps: Readonly<P>): void {
    if (prevProps.lang !== this.props.lang) {
      this.importRecaptcha()
    }
  }

  render () {
    const { apiKey, className, handleChange, lang } = this.props
    const { Recaptcha } = this.state

    return (
      <div>
        {Recaptcha && (
          <Recaptcha
            sitekey={apiKey}
            size={'normal'}
            onChange={handleChange}
          />
        )}
      </div>
    )
  }
}