useState set 方法不会立即反映更改

时间:2021-07-01 07:20:08

标签: reactjs react-hooks

state 没有立即反映变化,导致我不得不在 onSubmit 上玩两次才能提交表单

If you want to perform an action on state update, you need to use the useEffect hook, much like using componentDidUpdate in class components since the setter returned by useState doesn 't have a callback pattern

来自Link to suggested question

但老实说,我对如何将 on Submit 实现为使用效果感到困惑,对不起,我是新来的反应

  const onSubmit = async(data) = > {
      setNameError(nameValidation(data.name));
      setphoneError(phoneNumberValidation(data.phoneNumber));
      setEmailError(emailValidation(data.email));
      setMessageError(messageValidation(data.message));

//这里是我被抓到的地方,在反应开发工具中,上述状态被设置为假,但低于 noErrors 变量在所有条件检查为真后仍为假,无错误仍在获取旧值出于某种原因,我什至使用了 settimeout 方法。

   let noErrors = (!nameError && !phoneError && !emailError && !messageError);
      if (noErrors) {
          try {
              //  const templateParams = {
              //    name: data.name,
              //    email: data.email,
              //    number: data.phoneNumber,
              //    message: data.message,
              //  };
              //  await emailjs.send(
              //    process.env.REACT_APP_SERVICE_ID,
              //    process.env.REACT_APP_TEMPLATE_ID,
              //    templateParams,
              //    process.env.REACT_APP_USER_ID
              //  );
              reset();
              toastifySuccess();
          } catch (e) {
              console.log(e);
          }
      }
  };

const hasCharacter = /[a-zA-Z]/g;
export const nameValidation = function nameValidation(name) {
    if (name.length > 30) {
        return 'This field only accepts 30 characters';
    }
    if (name.length < 5) {
        return 'This field requires five characters';
    }
    if (/\d/.test(name)) {
        return ' This field cannot contain numbers';
    }
    if (!name.includes(' ')) {
        return 'This Field Requires A Space';
    }
    return false;
};
export const phoneNumberValidation = (number) = > {
    if (number.length !== 10) {
        return 'A Phone Number Must be ten digits';
    }
    if (hasCharacter.test(number)) {
        return 'A Phone Number Shouldnt Contain A Letter';
    }
    return false;
};
export const emailValidation = (email) = > {
    if (email.length > 30) {
        return 'This field only accepts 30 characters';
    }
    if (email.length < 5) {
        return 'This field requires five characters';
    }
    if (!email.includes('@')) {
        return 'Email Addresses require @ Symbol';
    }
    return false;
};
export const messageValidation = (message) = > {
    if (message.length > 500) {
        return 'This field only accepts 500 characters';
    }
    if (message.length < 5) {
        return 'This field requires five characters';
    }
    return false;
};

1 个答案:

答案 0 :(得分:1)

这里有两种方法可以解决您的问题。

将错误存储在局部变量中,并使用这些变量来设置状态并检查 noError。

const onSubmit = async(data) = > {
      const nameErr = nameValidation(data.name);
      const phoneErr = nameValidation(data.phoneNumber);
      const emailErr = nameValidation(data.email);
      const messageErr = nameValidation(data.message);
      setNameError(nameErr);
      setphoneError(phoneErr);
      setEmailError(emailErr);
      setMessageError(messageErr);
      let noErrors = (!nameErr && !phoneErr && !emailErr && !messageErr);
      // rest of your code
}

使用 useEffect 计算 noErrors

const onSubmit = async(data) = > {
    setNameError(nameValidation(data.name));
    setphoneError(phoneNumberValidation(data.phoneNumber));
    setEmailError(emailValidation(data.email));
    setMessageError(messageValidation(data.message));
}
useEffect(() => {
    const submitForm = async () => {
      let noErrors = (!nameErr && !phoneErr && !emailErr && !messageErr);
      if (noErrors) {
          try {
              //  const templateParams = {
              //    name: data.name,
              //    email: data.email,
              //    number: data.phoneNumber,
              //    message: data.message,
              //  };
              //  await emailjs.send(
              //    process.env.REACT_APP_SERVICE_ID,
              //    process.env.REACT_APP_TEMPLATE_ID,
              //    templateParams,
              //    process.env.REACT_APP_USER_ID
              //  );
              reset();
              toastifySuccess();
          } catch (e) {
              console.log(e);
          }
        }
     }
     submitForm();

},[nameError, phoneError, emailError, messageError])