React注册表单确认密码不匹配时错误信息不显示问题
问题根因
控制台抛出的innerHTML相关报错本质是Cannot set properties of null (setting 'innerHTML'),触发原因有两个:
- 类选择器书写错误:你在
querySelector中写的pseudo.error/email.error/password.error/password-confirm.error都漏了类选择器的前缀.,这种写法会匹配对应标签名的元素,而你页面里的错误提示容器是带两个类名的div,正确选择器应该是.pseudo.error这类格式,选择器写错导致querySelector返回null,给null赋值innerHTML就会触发报错。 - 服务条款复选框选择器错误:复选框只设置了
id="terms",没有加class="terms",你写的.terms选择器是匹配class为terms的元素,根本拿不到复选框DOM,后续访问terms.checked时也会触发空值错误。
修复方案
临时修复(不推荐,不符合React开发规范)
如果暂时要沿用原生DOM操作的写法,做两处修改即可:
- 给复选框加上对应的类名:
<input type="checkbox" id="terms" className="terms" /> - 修正所有错误的选择器,给类名前补上
.:const terms = document.querySelector(".terms"); const termsError = document.querySelector(".terms.error"); const pseudoError = document.querySelector(".pseudo.error"); const emailError = document.querySelector(".email.error"); const passwordError = document.querySelector(".password.error"); const passwordConfirmError = document.querySelector(".password-confirm.error");
标准React写法(强烈推荐)
React本身是数据驱动视图的框架,不需要手动操作DOM更新内容,直接用状态管理错误提示即可,从根源上避免DOM选择器匹配错误的问题,代码可维护性更高:
import { useState } from "react"; import axios from "axios"; const SignUpForm = () => { const [pseudo, setPseudo] = useState(""); const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [controlPassword, setControlPassword] = useState(""); const [agreeTerms, setAgreeTerms] = useState(false); // 统一管理表单错误信息 const [errors, setErrors] = useState({ pseudo: "", email: "", password: "", passwordConfirm: "", terms: "" }); const handleRegister = async (e) => { e.preventDefault(); const newErrors = { pseudo: "", email: "", password: "", passwordConfirm: "", terms: "" }; let valid = true; if (password !== controlPassword) { newErrors.passwordConfirm = "Les mots de passe ne correspondent pas"; valid = false; } if (!agreeTerms) { newErrors.terms = "Veuillez valider les conditions générales"; valid = false; } setErrors(newErrors); if (!valid) return; // 校验通过后再执行注册接口请求逻辑 }; return ( <form onSubmit={handleRegister} id="sign-up-form"> <label htmlFor="pseudo">Pseudo</label> <br /> <input type="text" name="pseudo" id="pseudo" onChange={(e) => setPseudo(e.target.value)} value={pseudo} /> <div className="pseudo error">{errors.pseudo}</div> <br /> <label htmlFor="email">Email</label> <br /> <input type="text" name="email" id="email" onChange={(e) => setEmail(e.target.value)} value={email} /> <div className="email error">{errors.email}</div> <br /> <label htmlFor="password">Mot de passe</label> <br /> <input type="password" name="password" id="password" onChange={(e) => setPassword(e.target.value)} value={password} /> <div className="password error">{errors.password}</div> <br /> <label htmlFor="password-confirm">Confirmer mot de passe</label> <br /> <input type="password" name="password-confirm" id="password-confirm" onChange={(e) => setControlPassword(e.target.value)} value={controlPassword} /> <div className="password-confirm error">{errors.passwordConfirm}</div> <br /> <input type="checkbox" id="terms" checked={agreeTerms} onChange={(e) => setAgreeTerms(e.target.checked)} /> <label htmlFor="terms"> J'accepte les{" "} <a href="/" target="_blank" rel="noopener noreferrer"> conditions generales </a> </label> <div className="terms error">{errors.terms}</div> <input type="submit" value="Valider l'inscription" /> </form> ); }; export default SignUpForm;
额外修正了你代码里的两处笔误:a标签的target="_blnk"改为正确的target="_blank",rel="noopener noreferer"改为正确的rel="noopener noreferrer",同时补上了缺失的useState导入。
内容的提问来源于stack exchange,提问作者pusat_almdr
相关产品推荐
相关产品推荐

