Reactjs 使用react钩子在提交失败后恢复表单提交状态
如果表单提交失败,我想恢复表单状态。 这是我的后续问题Reactjs 使用react钩子在提交失败后恢复表单提交状态,reactjs,Reactjs,如果表单提交失败,我想恢复表单状态。 这是我的后续问题 const useCbOnce=(cb)=>{ const[called,setCalled]=useState(false); //当重新渲染出现问题时,可以将下面的内容包装在useCallback中 返回(e)=>{ 如果(!调用){ setCalled(true); cb(e); } } } 常量MyForm=(道具)=>{ const[name,setName]=useState(); const handleSubmit=useC
const useCbOnce=(cb)=>{
const[called,setCalled]=useState(false);
//当重新渲染出现问题时,可以将下面的内容包装在useCallback中
返回(e)=>{
如果(!调用){
setCalled(true);
cb(e);
}
}
}
常量MyForm=(道具)=>{
const[name,setName]=useState();
const handleSubmit=useCbOnce((e)=>{
e、 预防默认值()
如果(姓名){
//一切都很好
}否则{
console.log('请输入名称并再次提交')
//名称为空我需要恢复表单状态以允许用户设置并重新提交
}
console.log('submitted!')
});
返回setName(e.target.value)}/>;
}
假设我提交了一个表单,但没有设置名称!我想恢复以前的表单状态,以便usr可以填写名称并重新提交表单。基本上再次调用setCalled(false),但不确定在何处执行此操作。您可以修改自定义挂钩以使用回调的返回值来决定提交是否成功。使用该返回值,钩子可以在第一次成功调用后停止允许提交
const useCbOnceOrRetryOnFail = (cb) => {
const [succeeded, setSucceeded] = useState(false);
return (e) => {
if (!succeeded) {
setSucceeded(cb(e));
}
}
}
// Usage:
const handleSubmit = useCbOnceOrRetryOnFail((e) => {
e.preventDefault()
if (!name) {
console.log('please enter the name and submit again')
return false; // Remember to set to false whenever fails
}
console.log('submitted!')
return true;
});
使用异步回调:
const useCbOnceOrRetryOnFail = cb => {
const [success, setSuccess] = useState(false);
return e => {
if (!success) {
setSuccess(true);
cb(e, setSuccess);
} else {
e.preventDefault(); // Still need to preventDefault if clicked again
}
};
};
const handleSubmit = useCbOnceOrRetryOnFail((e, setSuccess) => {
e.preventDefault();
if (!name) {
console.log("please enter the name and submit again");
setSuccess(false); // Remember to set to false whenever fails
} else {
console.log("submitted!");
authenticate.then(() => {
setSuccess(true);
}).catch(() => {
setSuccess(false);
});
}
});
请注意,我们需要传递
setSuccess
回调,而不是简单地返回。这是因为调用api是异步的,我们需要在解决/拒绝api时更新成功状态。您可以让useCbOnce
同时返回once
函数和reset
函数:
const useCbOnce=()=>{
const[called,setCalled]=useState(false);
返回{
//当重新渲染出现问题时,可以将下面的内容包装在useCallback中
一次:(cb)=>(e)=>{
如果(!调用){
setCalled(true);
cb(e);
}
},
重置:()=>setCalled(false);
}
}
常量MyForm=(道具)=>{
const[name,setName]=useState();
const{cbonence,reset}=useCbOnce();
const handleSubmit=cbOnce((e)=>{
e、 预防默认值()
如果(姓名){
console.log('submitted!')
//一切都很好
}否则{
console.log('请输入名称并再次提交')
重置();
}
});
返回(
setName(e.target.value)}/>
);
}
hello@stackoverflow newbie我正在测试这种方法,但是当我设置return false作为失败的api调用的结果时遇到了一个问题。例如,authenticate.then(console.log('all good').catch(error=>return false);return true如何控制这种情况?非常感谢您的帮助,因为api调用涉及更多,我将更新我的答案以适应这种情况。更新了我的答案:)
const useCbOnceOrRetryOnFail = cb => {
const [success, setSuccess] = useState(false);
return e => {
if (!success) {
setSuccess(true);
cb(e, setSuccess);
} else {
e.preventDefault(); // Still need to preventDefault if clicked again
}
};
};
const handleSubmit = useCbOnceOrRetryOnFail((e, setSuccess) => {
e.preventDefault();
if (!name) {
console.log("please enter the name and submit again");
setSuccess(false); // Remember to set to false whenever fails
} else {
console.log("submitted!");
authenticate.then(() => {
setSuccess(true);
}).catch(() => {
setSuccess(false);
});
}
});