如何为React账户创建模块代码添加邮箱、姓名、密码字段校验功能
字段校验功能实现方案
本次实现的默认校验规则如下,可根据需求自行调整:
- 姓名:非空,最小长度2位
- 邮箱:非空,符合标准邮箱格式
- 密码:非空,最小长度6位
1. 新增全局校验工具函数
在context.js顶部添加以下代码:
// 姓名校验 const validateName = (name) => { if (!name || name.trim() === '') return '姓名不能为空'; if (name.trim().length < 2) return '姓名长度不能少于2位'; return null; }; // 邮箱校验 const validateEmail = (email) => { const emailReg = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!email || email.trim() === '') return '邮箱不能为空'; if (!emailReg.test(email.trim())) return '请输入有效的邮箱格式'; return null; }; // 密码校验 const validatePassword = (password) => { if (!password || password === '') return '密码不能为空'; if (password.length < 6) return '密码长度不能少于6位'; return null; };
2. 重构CardForm组件,支持错误提示
替换context.js中原有的CardForm代码:
function CardForm(props) { const ctx = React.useContext(UserContext); // 存储各字段错误信息 const [errors, setErrors] = React.useState({ name: null, email: null, password: null, amount: null }); const handleNameChange = (e) => { const value = e.currentTarget.value; ctx.name = value; setErrors(prev => ({...prev, name: validateName(value)})); }; const handleEmailChange = (e) => { const value = e.currentTarget.value; ctx.email = value; setErrors(prev => ({...prev, email: validateEmail(value)})); }; const handlePasswordChange = (e) => { const value = e.currentTarget.value; ctx.password = value; setErrors(prev => ({...prev, password: validatePassword(value)})); }; const handleAmountChange = (e) => { const value = e.currentTarget.value; ctx.balance = value; setErrors(prev => ({...prev, amount: Number(value) <= 0 ? '金额必须大于0' : null})); }; // 暴露校验方法给父组件调用 React.useEffect(() => { if (props.onValidate) { props.onValidate(() => { const newErrors = { name: props.showName !== 'none' ? validateName(ctx.name) : null, email: props.showEmail !== 'none' ? validateEmail(ctx.email) : null, password: props.showPassword !== 'none' ? validatePassword(ctx.password) : null, amount: props.showAmount !== 'none' ? (Number(ctx.balance) > 0 ? null : '金额必须大于0') : null }; setErrors(newErrors); return !Object.values(newErrors).some(err => err !== null); }); } }, [ctx, props]); return ( <> <div style={{maxWidth: "18rem"}}> <div className="name-field" style={{display: props.showName}}> Name<br/> <input type="input" id="txtName" className={`form-control ${errors.name ? 'is-invalid' : ''}`} placeholder="Enter name" onChange={handleNameChange} /> {errors.name && <div className="invalid-feedback d-block mb-2">{errors.name}</div>} <br/> </div> <div className="email-field" style={{display: props.showEmail}}> Email address<br/> <input type="input" id="txtEmail" className={`form-control ${errors.email ? 'is-invalid' : ''}`} placeholder="Enter email" onChange={handleEmailChange}/> {errors.email && <div className="invalid-feedback d-block mb-2">{errors.email}</div>} <br/> </div> <div className="password-field" style={{display: props.showPassword}}> Password<br/> <input type="password" id="txtPassword" className={`form-control ${errors.password ? 'is-invalid' : ''}`} placeholder="Enter password" onChange={handlePasswordChange}/> {errors.password && <div className="invalid-feedback d-block mb-2">{errors.password}</div>} <br/> </div> <div className="amount-field" style={{display: props.showAmount}}> Amount<br/> <input type="number" className={`form-control ${errors.amount ? 'is-invalid' : ''}`} placeholder="Enter amount" onChange={handleAmountChange}/> {errors.amount && <div className="invalid-feedback d-block mb-2">{errors.amount}</div>} <br/> </div> </div> </> ) }
3. 修改CreateAccount组件,提交前触发校验
替换createAccount.js中原有的代码:
function CreateAccount(props){ const [show, setShow] = React.useState(true); const [status, setStatus] = React.useState(''); const ctx = React.useContext(UserContext); const [validateForm, setValidateForm] = React.useState(null); function addUser() { // 校验不通过直接拦截提交 if (!validateForm || !validateForm()) { setStatus('请修正表单中的错误后再提交'); setTimeout(() => setStatus(''), 3000); return; } ctx.balance = '0'; fetch(`/account/find/${ctx.email}`) .then(response => response.json()) .then(data => { console.log(data); if (data.length===0) ctx.user = true; }) .then(() => { if (ctx.user===true) { const url = `/account/create/${ctx.name}/${ctx.email}/${ctx.password}/${ctx.balance}`; (async () => { var res = await fetch(url); var data = await res.json(); console.log(data); })(); ctx.user=''; setShow(false); } else { ctx.user=''; setStatus('User already exists with that email'); setTimeout(() => setStatus(''),3000); }}) } return ( <Card bgcolor="primary" header="Create Account" text="" status={status} body={ <> {show ? <> <CardForm setShow={setShow} showAmount="none" onValidate={validateFn => setValidateForm(() => validateFn)} /> <button type="submit" className="btn btn-light" onClick={addUser}>Create Account</button> </> : <Success setShow={setShow}/>} </> } /> ); } function Success(props) { return ( <> <h5>Success!</h5><br/> <button type="submit" className="btn btn-light" onClick={() => props.setShow(true)}>Add another account</button> </> ) }
以上方案兼容Bootstrap自带的错误样式,同时实现了输入时实时校验、提交前统一拦截双重校验机制,存款模块也可以复用同一套校验逻辑。
内容的提问来源于stack exchange,提问作者manish gupta
相关产品推荐
相关产品推荐

