從表單提交處理程序內部呼叫自訂鉤子 setState 不會更新狀態
P粉976488015
P粉976488015 2023-09-16 11:39:44
0
1
990

表單中的欄位要求我注意它們才能顯示錯誤訊息。我希望在我尚未聚焦字段時單擊“提交”時出現錯誤訊息。

這是鉤子(懷疑是關於稍後的 setIsTouched 呼叫):

const useInputModifed = (validationArray) => {
  const [enteredValue, setEnteredValue] = useState("");
  const [isTouched, setIsTouched] = useState(false);

  //   [{errorName:,fn:validationFn}]
  let errorArray = [];

  for (const errorEntry of validationArray) {
    if (errorEntry.isErrorFn(enteredValue)) {
      errorArray.push(errorEntry.errorName);
    }
  }

  const hasError = errorArray.length > 0 && isTouched;

  const valueChangeHandler = (event) => {
    setEnteredValue(event.target.value);
  };

  const reset = () => {
    setEnteredValue("");
    setIsTouched(false);
  };

  console.log(errorArray, isTouched);

  return {
    value: enteredValue,
    validationArray: errorArray,
    hasError,
    valueChangeHandler,
    setIsTouched,
    isTouched,
    reset,
  };
};

這是表單處理程序(我為每個欄位使用了別名):

const formSubmissionHandler = (event) => {
    event.preventDefault();
    touchNameField(true);
    touchEmailField(true);


    if (nameInputHasError || emailInputHasError) {
 //console logging both fields gives false even after touching
      return;
    }
  
    if (!nameInputHasError && !emailInputHasError) {
      resetNameInput();
      resetEmailInput();
    }
  };

以驗證名稱欄位為空為例,我點擊開頭的提交按鈕。 目前在 const hasError = errorArray.length > 0 && isTouched; 中,數組有元素,但 isTouched 為 false,因為我沒有聚焦該字段。

然後是「touchNameField(true);」進來了。我嘗試使 hasError 為 true,但它仍然顯示為 false。

setState 呼叫是異步的,這是問題所在嗎?如果我刪除重置調用它就可以了。但我仍然不明白為什麼 nameInputError 等是 false。

P粉976488015
P粉976488015

全部回覆(1)
P粉057869348

如果不運行它,我相信這是因為 errorArrayhasError 對更改沒有反應。因此,這也取決於您實例化該鉤子的位置。 如果不進行測試,我會嘗試以下操作:

const useInputModifed = (validationArray) => {
  const [enteredValue, setEnteredValue] = useState("");
  const [isTouched, setIsTouched] = useState(false);

  const [errorArray, setErrorArray] = useState([]);
  const [hasError, setHasError] = useState(false);

  useEffect(() => {
    const newErrorArray = [];
    for (const errorEntry of validationArray) {
      if (errorEntry.isErrorFn(enteredValue)) {
        newErrorArray.push(errorEntry.errorName);
      }
    }
    setErrorArray(newErrorArray);
  }, [validationArray, enteredValue])

  useEffect(() => {
    setHasError(errorArray.length && isTouched);
  }, [errorArray, isTouched])

  const valueChangeHandler = (event) => {
    setEnteredValue(event.target.value);
  };

  const reset = () => {
    setEnteredValue("");
    setIsTouched(false);
  };

  console.log(errorArray, isTouched);

  return {
    value: enteredValue,
    validationArray: errorArray,
    hasError,
    valueChangeHandler,
    setIsTouched,
    isTouched,
    reset,
  };
};

同樣,未經測試,您可能需要一些調整。

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板