所以我有一个我以前在Vue中做过的项目,现在正在React(w / hooks)中进行学习。我遇到了一些问题,担心我没有以正确的方式进行操作(确定我不是)。
我遇到的最大问题之一是通过onchange和onblur更新状态。很多时候,状态值会落后一格。我发现使用旧类组件可以在setState中使用回调。 我正在尝试在用户更新字段时显示/隐藏即时表单验证反馈。
使用钩子应该使用useEffect来完成。我现在正在“工作”,但似乎渲染的次数超过了应有的次数。我可以知道它运行两次checkValues()来显示当前状态值的事实。
我误解的性质的一个示例是,如果我不将setinValid(validateForm());
放在onchange和useEffect中。它不会更新inValid的状态,后者会禁用/启用提交按钮。这对我来说似乎是多余的,我不确定为什么它会“按原样”工作。
任何对如何正确执行我正在尝试的操作的帮助/见解将不胜感激。
import React from "react";
import { Link } from "react-router-dom";
// import { saveUserToLocalStorage } from "../../utils/StorageHelper";
// import { User } from "../../utils/UserClass";
const UserAdd = props => {
const [userName, setuserName] = React.useState("");
const [userAge, setuserAge] = React.useState("");
const [userEmail, setuserEmail] = React.useState("");
const [inValid, setinValid] = React.useState(true);
const [errors, setErrors] = React.useState({
name: [],
age: [],
email: []
});
React.useEffect(() => {
checkValues();
setinValid(validateForm());
}, [userName, userAge, userEmail, inValid]);
const validateForm = () => {
if (isNaN(userAge)) {
return true;
}
if (!userName || !userAge || !userEmail) {
return true;
}
if (!validateEmail(userEmail)) {
return true;
}
return false;
};
function checkIndividualErrors() {
if (userName.length === 0) {
setErrors({ ...errors, name: ["User name is required"] });
} else {
setErrors({ ...errors, name: [] });
}
}
const checkValues = () => {
console.log(
"username:",
userName,
"age:",
userAge,
"useremail: ",
userEmail,
"invalid:",
inValid
);
};
const validateEmail = mail => {
if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(mail)) {
return true;
}
return false;
};
return (
<div>
<h2 class="line-container">
<span>Add a new User</span>
</h2>
<hr />
<div class="field is-horizontal">
<div class="field-label is-normal">
<label class="label">Name</label>
</div>
<div class="field-body">
<div class="field">
<p class="control">
<input
class="input"
type="text"
name="name"
placeholder="Name"
value={userName}
onChange={e => {
setuserName(e.target.value);
setinValid(validateForm());
checkIndividualErrors();
}}
onBlur={checkIndividualErrors}
/>
<span class="error">{errors.name}</span>
</p>
</div>
</div>
</div>
<div class="field is-horizontal">
<div class="field-label is-normal">
<label class="label">Age</label>
</div>
<div class="field-body">
<div class="field">
<p class="control">
<input
class="input"
type="text"
name="age"
placeholder="Age"
value={userAge}
onChange={e => {
setuserAge(e.target.value);
setinValid(validateForm());
// checkIndividualErrors not fully implemented yet
}}
/>
<span class="error" />
</p>
</div>
</div>
</div>
<div class="field is-horizontal">
<div class="field-label is-normal">
<label class="label">Email</label>
</div>
<div class="field-body">
<div class="field">
<p class="control">
<input
class="input"
type="email"
name="email"
placeholder="Email"
value={userEmail}
onChange={e => {
setuserEmail(e.target.value);
setinValid(validateForm());
// checkIndividualErrors not fully implemented yet
}}
/>
<span class="error" />
</p>
</div>
</div>
</div>
<p class="" style={{ margin: "0 auto" }}>
<button
disabled={inValid}
class="button is-primary"
style={{ marginRight: "10px" }}
>
Create
</button>
<Link to="/" class="button">
Cancel
</Link>
<Link to="/" class="goBack">
<span style={{ fontSize: "20px" }}>←</span>
</Link>
</p>
</div>
);
};
export default UserAdd;