从表单提交处理程序内部调用自定义钩子 setState 不会更新状态
P粉976488015
P粉976488015 2023-09-16 11:39:44
0
1
931

表单中的字段要求我关注它们才能显示错误消息。我希望在我尚未聚焦字段时单击“提交”时出现错误消息。

这是钩子(怀疑是关于稍后的 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,
  };
};

同样,未经测试,您可能需要一些调整。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板