React项目中Google reCAPTCHA首次加载不渲染问题求助
问题描述
Google reCAPTCHA在页面首次加载时无法渲染;提交表单跳转到其他页面后,通过浏览器返回按钮回到表单页面时可正常渲染,但重新加载页面后又无法渲染。
相关代码
index.html中的脚本引入
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
React组件代码
import React, { useState, useRef } from "react"; import LogoBig from "../../../Assets/LogoBig.png"; import { ToastContainer, toast } from "react-toastify"; import "react-toastify/dist/ReactToastify.css"; import { validateEmail, validatePassword, } from "../../../Components/FormValidation"; import { MdKeyboardArrowDown } from "react-icons/md"; import ReCAPTCHA from "react-google-recaptcha"; const UserRegister = () => { const [nom, setNom] = useState(""); const [prenom, setPrenom] = useState(""); // ... 省略其他state定义 const [recaptchaValue, setRecaptchaValue] = useState(""); const handleRecaptcha = (value) => { console.log("reCAPTCHA value:", value); setRecaptchaValue(value); }; const handleSubmit = async (e) => { if (e && typeof e.preventDefault === "function") { e.preventDefault(); const token = recaptchaValue; console.log('tokenCaptcha', token) recaptchaValue.reset(); // 此处存在错误 } const formData = new URLSearchParams(); formData.append("nom", nom); formData.append("prenom", prenom); // ... 省略其他表单字段 formData.append("recaptcha", recaptchaValue); formData.append("profile", "Unfinished"); fetch("http://localhost:5000/register", { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: formData, }) .then((res) => res.json()) .then((data) => { if (data !== "Email already in use") { console.log("success"); // window.location.reload(); // window.location.href = "/confirmation"; } else { if (data === "Email already in use") { setRegisterError("Cette adresse e-mail est déjà utilisée"); } else { setError(data); console.log(error); } } }); }; return ( // ... 省略其他组件内容 <ReCAPTCHA sitekey="6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI" onChange={handleRecaptcha} /> // ... 省略其他组件内容 ); };
解决方案
1. 移除全局reCAPTCHA脚本引入
react-google-recaptcha组件会自动加载reCAPTCHA API脚本,手动在index.html中引入会导致脚本重复加载,引发渲染冲突。删除index.html中的以下代码:
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
2. 用useRef控制reCAPTCHA实例
组件首次加载时可能因API脚本未就绪导致渲染失败,通过ref可以手动触发重新渲染:
- 给
ReCAPTCHA组件添加ref属性 - 组件挂载后检查实例状态,若未渲染则手动调用
render方法
修改后的组件代码片段:
import React, { useState, useRef, useEffect } from "react"; // ... 其他引入 const UserRegister = () => { // ... 其他state定义 const recaptchaRef = useRef(null); useEffect(() => { // 组件挂载后检查并重新渲染reCAPTCHA if (recaptchaRef.current) { recaptchaRef.current.reset(); recaptchaRef.current.render(); } }, []); // ... 其他方法 return ( // ... 其他内容 <ReCAPTCHA ref={recaptchaRef} sitekey="6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI" onChange={handleRecaptcha} /> // ... 其他内容 ); };
3. 修复reset方法调用错误
原代码中直接调用recaptchaValue.reset()是错误的,recaptchaValue是存储token的字符串,并非组件实例。需通过ref调用reset:
// 原错误代码 recaptchaValue.reset(); // 修改后 recaptchaRef.current?.reset();
4. 监听脚本加载完成事件
如果仍存在渲染问题,可通过组件的asyncScriptOnLoad属性监听脚本加载完成,再触发渲染:
const handleScriptLoad = () => { recaptchaRef.current?.render(); }; // 在ReCAPTCHA组件中添加属性 <ReCAPTCHA ref={recaptchaRef} sitekey="6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI" onChange={handleRecaptcha} asyncScriptOnLoad={handleScriptLoad} />
内容的提问来源于stack exchange,提问作者Ons Jannet
相关产品推荐
相关产品推荐

