簡體   English   中英

使用反應鈎子在提交失敗后恢復表單提交狀態

[英]Restore form submission state after failed submission with react hooks

如果表單提交失敗,我想恢復表單狀態。 這是關於在 reactjs 中防止多個表單提交的后續問題

const useCbOnce = (cb) => {
    const [called, setCalled] = useState(false);

    // Below can be wrapped in useCallback whenever re-renders becomes a problem
    return (e) => {
        if (!called) {
            setCalled(true);
            cb(e);
        }
    }
}

const MyForm = (props) => {
    const [name, setName] = useState();
    const handleSubmit = useCbOnce((e) => {
        e.preventDefault()
        if (name) {
            //all is good
        } else {
            console.log('please enter the name and submit again')
            // name is empty I need to restore the form state to allow the user to set and resubmit
        }
        console.log('submitted!')
    });
    return <form onSubmit={ handleSubmit }><input onChange={ (e) => setName(e.target.value) } /></form>;
}

假設我提交了一個表單而不設置名稱! 我想恢復以前的表單狀態,以便 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 是異步的,我們需要在它被解決/拒絕時更新成功狀態。

您可以讓useCbOnce返回once函數和reset函數:

const useCbOnce = () => {
    const [called, setCalled] = useState(false);

    return {
      // Below can be wrapped in useCallback whenever re-renders becomes a problem
      once: (cb) => (e) => {
        if (!called) {
            setCalled(true);
            cb(e);
        }
      },
      reset: () => setCalled(false);
    }
}

const MyForm = (props) => {
    const [name, setName] = useState();
    const { cbOnce, reset } = useCbOnce();

    const handleSubmit = cbOnce((e) => {
        e.preventDefault()
        if (name) {
            console.log('submitted!')
            //all is good
        } else {
            console.log('please enter the name and submit again')
            reset();
        }
    });

    return (
      <form onSubmit={handleSubmit}>
        <input onChange={e => setName(e.target.value)} />
      </form>
    );
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM