reactjs - react-hook useFormInput()表单验证不起作用
问题描述
链接到代码沙箱https://stackblitz.com/edit/react-cdv6mx?devtoolsheight=33&file=src/ResetPassword.js
解释: 当用户输入不正确的详细信息时,服务器会发送 400: bad request error 和一条消息,该消息可以在Response tab
网络选项卡下看到。目的是在提交表单之前验证表单字段,并在输入不正确的字段时显示错误消息。此外,目的是禁用重置按钮,直到表单字段符合条件。因此,这将防止用户意外提交半输入的字段。
我有一个功能组件,其中有一个简单的形式。
问题:我正在调用validatForm()
方法onChange
。该方法应首先检查 newPassword 和 confirmPassword 是否相同,并且是否符合密码规则(要求),如果为真,则仅发送数据。
更新的代码在上面的 STACKBLITZ 链接中。
我使用useFormInput()
如下
const email = useFormInput("");
const newPassword = useFormInput("");
const confirmPassword = useFormInput("");
我写了一个useFormInput()
方法
const useFormInput = (initialValue) => {
const [value, setValue] = useState(initialValue);
const handleChange = (e) => {
setValue(e.target.value);
};
return {
value,
onChange: handleChange,
};
};
和一个validateForm()
方法,我把它传给我<button/>
/* Your password must contain at least one capital letter, one
*number and one lowercase letter, and it must contain at least 8
*characters*/
const validateForm = (event) => {
let pass = event.target.value;
let reg = /^(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9]).{8,}$/;
let test = reg.test(pass);
if (test) {
this.setState({ value: event.target.value });
} else {
alert("password validation unsuccessful. Please try again.");
return;
}
};
并在渲染()
<FormGroup row>
<Label for="Email" sm={2}>
Email
</Label>
<Col sm={4}>
<Input
type="email"
name="email"
id="Email"
{...email}
/>
</Col>
</FormGroup>
<FormGroup row>
<Label for="newPassword" sm={2}>
New Password
</Label>
<Col sm={4}>
<Input
type="password"
name="password"
id="newPassword"
{...newPassword}
/>
</Col>
</FormGroup>
<FormGroup row>
<Label for="confirmPassword" sm={2}>
Confirm Password
</Label>
<Col sm={4}>
<Input
type="password"
name="confirmPassword"
id="confirmPassword"
{...confirmPassword}
/>
</Col>
</FormGroup>
<div className="form-actions">
{error && (
<>
<small style={{ color: "red" }}>{error}</small>
<br />
</>
)}
<br />
<Col lg={{ offset: 2 }} sm={{ size: 1 }}>
<Button
className="mail-reset-btn"
block
type="submit"
value={loading ? "Loading..." : "Login"}
onClick={handleReset}
disabled={!validateForm}
>
Reset
</Button>
</Col>
</div>
</Form>
解决方案
更新您validateForm
以从表单onSubmit
事件中解构密码字段。创建一个errors
对象来跟踪存在哪些字段错误。如果errors
对象为空,则验证通过,否则设置错误状态。
const validateForm = event => {
event.preventDefault();
const { confirmPassword, newPassword } = event.target;
const errors = {};
const regex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9]).{8,}$/;
if (!regex.test(newPassword.value)) {
errors.requirementUnmet = "New password does not meet requirements.";
}
if (newPassword.value !== confirmPassword.value) {
errors.passwordMismatch = "Entered passwords do not match.";
}
if (!Object.keys(errors).length) {
alert("password validation successful.");
setError(null);
return;
}
setError(errors);
};
附加validateForm
到表单的onSubmit
句柄。
<Form onSubmit={validateForm}>
确保表单中有一个 type="submit" 按钮。
<Button
className="mail-submit-btn"
block
type="submit"
value={loading ? "Loading..." : "Login"}
>
Submit
</Button>
更新了 stackblitz(虽然我没有帐户,所以复制下面的更新代码。)
注意:为了简单起见,我只是简单JSON.stringify(error)
的错误,但你会想要更优雅地呈现它。
整个 ResetPassword.js
import React, { useState } from "react";
import {
Button,
Form,
FormGroup,
Input,
Col,
Label,
Modal,
ModalHeader,
ModalBody,
ModalFooter
} from "reactstrap";
const useFormInput = initialValue => {
const [value, setValue] = useState(initialValue);
const handleChange = e => {
setValue(e.target.value);
};
return {
value,
onChange: handleChange
};
};
const ResetPassword = props => {
// form inputs
const email = useFormInput("");
const newPassword = useFormInput("");
const confirmPassword = useFormInput("");
// using hooks
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const [modal, setModal] = useState(false);
const toggle = () => setModal(!modal);
const validateForm = event => {
event.preventDefault();
const { confirmPassword, newPassword } = event.target;
const errors = {};
const regex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9]).{8,}$/;
if (!regex.test(newPassword.value)) {
errors.requirementUnmet = "New password does not meet requirements.";
}
if (newPassword.value !== confirmPassword.value) {
errors.passwordMismatch = "Entered passwords do not match.";
}
if (!Object.keys(errors).length) {
alert("password validation successful.");
setError(null);
return;
}
setError(errors);
};
const handleReset = e => {
e.preventDefault();
setError(null);
setLoading(true);
// some unrelated redux code
};
return (
<div className="mail-reset" id="forgotPassword">
<div className="mail-reset-content">
<Form onSubmit={validateForm}>
<h3 className="form-title">Enter Information</h3>
<FormGroup row>
<Label for="Email" sm={2}>
Email
</Label>
<Col sm={4}>
<Input
type="email"
name="email"
id="Email"
placeholder="Email"
aria-label="email address"
aria-describedby="email address"
aria-invalid="false"
{...email}
/>
</Col>
</FormGroup>
<FormGroup row>
<Label for="newPassword" sm={2}>
New Password
</Label>
<Col sm={4}>
<Input
type="password"
name="password"
id="newPassword"
placeholder="New Password"
aria-label="new password"
aria-describedby="new password"
aria-invalid="false"
{...newPassword}
/>
</Col>
</FormGroup>
<FormGroup row>
<Label for="confirmPassword" sm={2}>
Confirm Password
</Label>
<Col sm={4}>
<Input
type="password"
name="confirmPassword"
id="confirmPassword"
placeholder="Confirm Password"
aria-label="new password"
aria-describedby="new password"
aria-invalid="false"
{...confirmPassword}
/>
</Col>
</FormGroup>
<div className="modal-wrapper">
<Col sm={{ size: 4, offset: 2 }}>
<Button onClick={toggle} className="passwordReqBtn">
Password Requirements
</Button>
</Col>
<Modal isOpen={modal} toggle={toggle} className="mail-reset-modal">
<ModalHeader toggle={toggle}>Password Requirements</ModalHeader>
<ModalBody>
Your password must contain at least one capital letter, one
number and one lowercase letter, and it must contain at least 8
characters
</ModalBody>
<ModalFooter>
<Button onClick={toggle} className="btn-modal pull-right">
OK
</Button>{" "}
</ModalFooter>
</Modal>
</div>
<div className="form-actions">
{error && (
<>
<small style={{ color: "red" }}>{JSON.stringify(error)}</small>
<br />
</>
)}
<br />
<Col lg={{ offset: 2 }} sm={{ size: 1 }}>
<Button
className="mail-reset-btn"
block
type="submit"
value={loading ? "Loading..." : "Login"}
>
Submit
</Button>
<Button
className="mail-reset-btn"
block
type="reset"
value={loading ? "Loading..." : "Login"}
onClick={handleReset}
>
Reset
</Button>
</Col>
</div>
</Form>
</div>
</div>
);
};
export default ResetPassword;
推荐阅读
- php - 尽管我根据功能创建了函数,但为什么会出现此错误?
- ios - 订阅用户的 OneSignal 订阅状态在重新启动我的应用程序时更改为“用户手动选择退出”
- reactjs - 决定运行时道具打字稿
- java - 在 Eclipse 中执行 java 类
- css - 如何使背景图像在所有屏幕中都具有响应性
- wordpress - 对博客帖子使用“团队成员”自定义帖子类型而不是作者
- php - 是否有可能在流明中获得 Auth::user?
- spring-boot - 从 apache camel spring 应用程序向 IBM -MQ 推送消息时出错
- excel - offset 为空单元格 excel 提供 0
- php - Wordpress - wp_get_object_terms - 多种分类法