我对此反应很新。在这里,我为一个项目做了一个小的表单组件(包括一些顺风)。表单的上方是一个隐藏的警告框,它将显示提交(绿色表示成功,红色表示失败)。我附加到表单上的处理程序显示了正确的警报,但是它需要两次单击。在处理程序validateFormData()中,我正在重置状态(isError)。我知道useState钩子是异步的,所以我的isError变量在呈现警告框之前没有正确更新(对吗?)我尝试过将回调传递给我的setIsError函数(在在线查找解决方案之后),但我无法解决这个问题。我在这里的球场对不对?还是我漏掉了什么?
function ContactInsert() {
const contactForm = useRef(null);
const alertBox = useRef(null);
const [isError, setIsError] = useState(false);
function showAlertBox() {
alertBox.current.classList.add("alert-show");
setTimeout(() => {
alertBox.current.classList.remove("alert-show");
}, 3000);
}
async function validateFormData() {
// unpack and validate data
const name = contactForm.current.querySelector("[name=name]").value.trim();
const email = contactForm.current.querySelector("[name=email]").value.trim();
const comment = contactForm.current.querySelector("[name=comment]").value.trim();
if (name.length > 0 && email.length > 0 && comment.length > 0) {
setIsError(false);
} else {
setIsError(true);
}
showAlertBox();
}
return (
<div className="flex flex-col">
<div className="flex justify-center my-2">
<h1>Drop me a message!</h1>
</div>
{isError ?
<div ref={alertBox} className="flex h-12 w-2/3 justify-center bg-[#ff462e] invisible">hello</div> :
<div ref={alertBox} className="flex h-12 w-2/3 justify-center bg-[#77ff6e] invisible">hello</div>
}
<form
className="flex flex-col items-center justify-center md:h-full"
method="POST"
name="contact"
id="contact"
type="submit"
ref={contactForm}
onSubmit={(e) => {
e.preventDefault();
validateFormData();
}}
>
<div className="flex flex-col justify-between w-2/3">
<label>name</label>
<input type="text" name="name"/>
</div>
<br/>
<div className="flex flex-col justify-between w-2/3">
<label>email</label>
<input type="text" name="email"/>
</div>
<br/>
<div className="flex flex-col justify-between w-2/3 h-40">
<label>comment</label>
<textarea className="h-full" name="comment"/>
</div>
<div className="flex w-2/3 justify-start my-4">
<button className="p-1" form="contact">Submit</button>
</div>
</form>
</div>
);
}发布于 2022-11-16 17:10:19
直接操作DOM总是一个坏主意,因为react将很难与呈现的输出匹配,并且违背了使用React的目的。最好是将这些信息存储在状态中,然后让react来处理它。
此外,setState是异步的,这将迫使react组件重定向。我们可以使用useEffect让React知道组件必须在下一次呈现时做一些事情。
function ContactInsert() {
const [isError, setIsError] = useState(false);
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [comment, setComment] = useState('');
const [displayAlert, setDisplayAlert] = useState(false);
const handleNameOnchangeHandler = (event) => {
setName(event.target.value);
};
const handleEmailOnchangeHandler = (event) => {
setName(event.target.value);
};
const handleCommentOnchangeHandler = (event) => {
setName(event.target.value);
};
const validateFormData = () => {
const hasError = !name || !email || !comment;
setIsError(hasError);
}
useEffect(() => {
if(isError) {
setDisplayAlert(true);
setTimeout(() => {
setDisplayAlert(false);
setIsError(false);
}, 3000);
}
}, [isError]);
return (
<div className="flex flex-col">
<div className="flex justify-center my-2">
<h1>Drop me a message!</h1>
</div>
{displayAlert ?
<div ref={alertBox} className="flex h-12 w-2/3 justify-center bg-[#ff462e] show-alert">hello</div> : null
}
<form
className="flex flex-col items-center justify-center md:h-full"
method="POST"
name="contact"
id="contact"
type="submit"
ref={contactForm}
onSubmit={(e) => {
e.preventDefault();
validateFormData();
}}
>
<div className="flex flex-col justify-between w-2/3">
<label>name</label>
<input type="text" name="name" onchange={handleNameOnchangeHandler}/>
</div>
<br/>
<div className="flex flex-col justify-between w-2/3">
<label>email</label>
<input type="text" name="email" onchange={handleEmailOnchangeHandler}/>
</div>
<br/>
<div className="flex flex-col justify-between w-2/3 h-40">
<label>comment</label>
<textarea className="h-full" name="comment" onchange={handleCommentOnchangeHandler}/>
</div>
<div className="flex w-2/3 justify-start my-4">
<button className="p-1" form="contact">Submit</button>
</div>
</form>
</div>
);
}这是一个使用useEffect的示例。不使用它也可以做到这一点。您还可以使用单个onchange处理程序,并根据触发事件的目标设置值。
发布于 2022-11-16 17:05:29
你的反应是完全错误的。我强烈建议您仔细阅读react并深入了解呈现概念。我在您的代码中看到的问题是:
。
使用ref更改css类的
https://stackoverflow.com/questions/74463918
复制相似问题