我有我要在其中实现电话验证的Web应用程序。我已经基于文档和示例初始化了recaptchaVerifier。但是,如果我想再次提交表单(例如由于错误)。我收到错误消息:Error: reCAPTCHA has already been rendered in this element
。
我尝试使用.clear
方法删除验证程序,但这似乎没有效果。波纹管是示例代码。
有什么我忽略的东西吗?
谢谢。
class PhoneAuth extends React.Component {
static contextTypes = {
firebase: PropTypes.object.isRequired,
};
state = {
phone: '',
}
onChangeHandler = (e) => {
this.setState({
[e.target.name]: e.target.value,
})
}
onPhoneLoginSubmit = (e) => {
const { onVerificationSend } = this.props
const {phone} = this.state
const {firebase }=this.context
e.preventDefault()
this.applicationVerifier = new firebase.auth.RecaptchaVerifier(
'recaptcha-container',
{ size: 'invisible' }
);
firebase.auth().signInWithPhoneNumber(phone, this.applicationVerifier)
.then((result) => {
onVerificationSend(result.verificationId)
this.applicationVerifier.clear()
})
.catch (error => {
this.setState({formError: error})
this.applicationVerifier.clear()
})
}
render() {
const { intl } = this.props;
const { phone, formError } = this.state
return (
<div>
<form onSubmit={this.onPhoneLoginSubmit} name="phone-signin" method="post">
<input
id="phone"
name="phone"
type="phone"
onChange={this.onChangeHandler}
value={phone}
/>
<label className="input__label" htmlFor="email">
phone number
</label>
{formError && (
<p >
{formError.code}
</p>
)}
<button
type="submit"
>
sign in
</button>
</form>
<div id="recaptcha-container"></div>
</div>
)
}
}
答案 0 :(得分:2)
所以,我知道了。问题不是clear()方法-工作正常。但是我必须从头开始重新创建验证码容器。 Doc不清楚,所以这让我感到困惑。在文档中有:
从页面上清除reCAPTCHA小部件并破坏当前实例。
所以我认为它将通过该方法删除。
所以,现在我在render方法中有以下代码:
<div ref={ref => this.recaptchaWrapperRef = ref}>
<div id="recaptcha-container"></div>
</div>
,然后在提交回调中:
if (this.applicationVerifier && this.recaptchaWrapperRef) {
this.applicationVerifier.clear()
this.recaptchaWrapperRef.innerHTML = `<div id="recaptcha-container"></div>`
}
// Initialize new reCaptcha verifier
this.applicationVerifier = new firebase.auth.RecaptchaVerifier(
'recaptcha-container',
{ size: 'invisible' }
);
这是我做出反应的唯一方法。如果有人仍然有更好的方法,请随时发布。我认为这很丑陋(对于React)。
答案 1 :(得分:0)
在onPhoneLoginSubmit()
方法之外使用captchaVarifier
请勿使用
this.applicationVerifier
this.applicationVerifier = new firebase.auth.RecaptchaVerifier(
'recaptcha-container',
{ size: 'invisible' }
);
请使用window.recaptchaVerifier并删除.clear()
window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier(
"recaptcha-container",
{
size: "invisible"
}
);
onPhoneLoginSubmit = (e) => {
firebase.auth().signInWithPhoneNumber(phone, window.recaptchaVerifier)
.then((result) => {
onVerificationSend(result.verificationId)
})
.catch (error => {
this.setState({formError: error})
})
}
然后使用setTimeout()
函数延迟1或2秒,如果您不使用setTimeout()
,则重新配置容器<div id="recaptcha-container"></div>
将在此代码之后执行,这将产生错误>
请使用setTimeout()
,例如下面的示例
componentWillMount(){
setTimeout(() => {
window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier(
"recaptcha-container",
{
size: "invisible"
}
);
}, 2000);
}
onPhoneLoginSubmit = (e) => {
firebase.auth().signInWithPhoneNumber(phone, window.recaptchaVerifier)
.then((result) => {
onVerificationSend(result.verificationId)
})
.catch (error => {
this.setState({formError: error})
})
}
答案 2 :(得分:0)
我在React上也遇到了同样的问题。但有一个参考的问题。所以我使用父div元素的ID创建了一个新实例
<div ref={ref => this.recaptchaWrapperRef = ref}>
<div id="recaptcha-container"></div>
</div>
在提交回调中添加它。
document.getElementById("recaptcha-container").innerHTML = "<div id='recaptcha'></div>";
答案 3 :(得分:0)
只需在catch中使用window.recaptchaVerifier.reset() 例如
const signInWithPhoneNumber = (fullMobile) => {
return new Promise((resolve, reject) => {
auth.signInWithPhoneNumber(fullMobile, window.recaptchaVerifier).then(res => {
resolve(res)
})
.catch(error => {
console.log(error)
window.recaptchaVerifier.reset()
reject(error)
})
})
}