如何解决为什么不验证eventListener上的输入有效?
您能帮我使此沙盒正常工作吗? 我想念东西。
当密码或登录名的长度大于3时,我想在输入附近看到“良好”而不是“失败”。
这是链接:https://codesandbox.io/s/competent-bogdan-5604u?file=/src/App.js
谢谢!
解决方法
有一些问题,但是它们都来自同一根-状态更新不会立即发生。
问题之一是您不能在调用setState
后立即使用更新的状态。这导致您的验证逻辑使用上一个呈现器中的表单值执行。
第二个问题是,如果您连续两次调用状态更新程序函数,它将仅使用最后一个值。因此,在验证逻辑中,您一次基于setFormError
的值调用login
,一次基于password
的值调用。这意味着将永远不会使用login
逻辑确定的值。
我已经写了一个可以正确编写此方法的示例。
作为每个输入更改调用的函数的示例一:
const { useState } = React;
const MyInput = (props) => {
return (
<input {...props} style={{ border: "1px solid red",outline: "none" }} />
);
};
const Example = () => {
const [form,setForm] = useState({
login: "",password: ""
});
const [formError,setFormError] = useState({
isValidLogin: "FAIL",isValidPassword: "FAIL"
});
const handleValidateForm = (newForm) => {
let newValid = {...formError}; // Use a new object so we only update state once
if (newForm.login.length > 3) {
newValid.isValidLogin = "GOOD"
} else {
newValid.isValidLogin = "FAIL"
}
if (newForm.password.length > 3) {
newValid.isValidPassword = "GOOD"
} else {
newValid.isValidPassword = "FAIL"
}
setFormError(newValid);
};
const onChange = (e) => {
e.preventDefault();
const { name,value } = e.target;
const newForm = {...form,[name]: value}; // Set to new object
setForm(newForm);
handleValidateForm(newForm); // Send the new object so its up-to-date
};
return (
<div>
<div>
<MyInput type="text" name="login" onChange={onChange} />{" "}
{formError.isValidLogin}
<br />
<MyInput type="text" name="password" onChange={onChange} />{" "}
{formError.isValidPassword}
</div>
</div>
);
};
ReactDOM.render(<Example />,document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
另一种方法是将验证移至useEffect
:
const { useState,useEffect } = React;
const MyInput = (props) => {
return (
<input {...props} style={{ border: "1px solid red",isValidPassword: "FAIL"
});
useEffect(() => {
let newValid = {...formError}; // Use a new object so we only update state once
if (form.login.length > 3) {
newValid.isValidLogin = "GOOD"
} else {
newValid.isValidLogin = "FAIL"
}
if (form.password.length > 3) {
newValid.isValidPassword = "GOOD"
} else {
newValid.isValidPassword = "FAIL"
}
setFormError(newValid);
},[form]); // Runs every time the form changes
const onChange = (e) => {
e.preventDefault();
const { name,value } = e.target;
setForm({...form,[name]: value});
};
return (
<div>
<div>
<MyInput type="text" name="login" onChange={onChange} />{" "}
{formError.isValidLogin}
<br />
<MyInput type="text" name="password" onChange={onChange} />{" "}
{formError.isValidPassword}
</div>
</div>
);
};
ReactDOM.render(<Example />,document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
它具有相同的效果,因此取决于您喜欢哪种模式。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。