搜尋

首頁  >  問答  >  主體

從表單提交處理程序內部呼叫自訂鉤子 setState 不會更新狀態

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

這是鉤子(懷疑是關於稍後的 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粉976488015P粉976488015443 天前939

全部回覆(1)我來回復

  • P粉057869348

    P粉0578693482023-09-17 10:21:46

    如果不運行它,我相信這是因為 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,
      };
    };
    

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

    回覆
    0
  • 取消回覆