【问题标题】:Form validation with multiple if statements on an onClick event在 onClick 事件上使用多个 if 语句进行表单验证
【发布时间】:2020-12-24 05:00:16
【问题描述】:

在使用多个 if 语句的 handleClick 函数内进行验证期间,只有最后一个将错误状态设置为 true (errors.sintomas: true),甚至将所有输入留空(其余的将其设置为 false,即错误的初始状态,从而防止输入获得除最后一个注释外的红色边框)。因此,将所有输入留空会给我一个错误状态:

{ 吉祥物:假, 产权:假, 费查:假的, 霍拉:假的, 圣托玛斯: 真的 }

为什么会这样?这是所有代码:

const Formulario = () => {
  const [cita, setCita] = useState({
    mascota: '',
    propietario: '',
    fecha: '',
    hora: '',
    sintomas: ''
  });

  const [errors, setErrors] = useState({
    mascota: false,
    propietario: false,
    fecha: false,
    hora: false,
    sintomas: false
  });

  const [triggerAnim, setTriggerAnim] = useState(false);

  const handleChange = (e) => {
    setCita({ ...cita, [e.target.name]: e.target.value });
  };

  const handleClick = (e) => {
    e.preventDefault();
    if (cita.mascota.trim().length < 1) {
      setErrors({ ...errors, mascota: true });
      setTriggerAnim(true);
    }
    if (cita.propietario.trim().length < 1) {
      setErrors({ ...errors, propietario: true });
      setTriggerAnim(true);
    }
    if (cita.fecha.trim().length < 1) {
      setErrors({ ...errors, fecha: true });
      setTriggerAnim(true);
    }
    if (cita.hora.trim().length < 1) {
      setErrors({ ...errors, hora: true });
      setTriggerAnim(true);
    }
    if (cita.sintomas.trim().length < 1) {
      setErrors({ ...errors, sintomas: true });
      setTriggerAnim(true);
    }
  };

  return (
    <Fragment>
      <h2>Crear una cita</h2>
      <form>
        <label htmlFor="mascota">Nombre de tu mascota:</label>
        <input
          type="text"
          name="mascota"
          className={`u-full-width ${errors.mascota ? 'error' : ''}`}
          placeholder="Nombre de la mascota"
          onChange={handleChange}
          value={cita.mascota}
        />
        <label htmlFor=" propietario">Nombre del propietario:</label>
        <input
          type="text"
          name="propietario"
          className={`u-full-width ${errors.propietario ? 'error' : ''}`}
          placeholder="Nombre del propietario"
          onChange={handleChange}
          value={cita.propietario}
        />
        <label htmlFor="fecha">Fecha:</label>
        <input
          type="date"
          name="fecha"
          className={`u-full-width ${errors.fecha ? 'error' : ''}`}
          onChange={handleChange}
          value={cita.fecha}
        />
        <label htmlFor="hora">Hora:</label>
        <input
          type="time"
          name="hora"
          className={`u-full-width ${errors.hora ? 'error' : ''}`}
          onChange={handleChange}
          value={cita.hora}
        />
        <label htmlFor="sintomas">Sintomas</label>
        <input
          type="text"
          name="sintomas"
          className={`u-full-width ${errors.sintomas ? 'error' : ''}`}
          placeholder="Síntomas de la mascota:"
          onChange={handleChange}
          value={cita.sintomas}
        />    
 
        <button className="button-primary u-full-width" onClick={handleClick}>
          Crear Cita
        </button>
      </form>
    </Fragment>
  );
};

export default Formulario;

不明白为什么只有最后一个 if 语句有效。 如果我使用 setErrors(prevState => {return {...prevState, mascota: true}) (具有先前状态的回调),那么突然一切正常。为什么使用对象扩展运算符更新状态不起作用?

【问题讨论】:

    标签: reactjs react-hooks


    【解决方案1】:

    如果您单击一次,整个handleClick 函数也将完全运行一次其代码。在那个handleClick 内部,errors 对象是恒定的并且永远不会发生变异;它指的是errors 在渲染期间在点击之前所包含的内容。

    假设最初的errors对象的值都是false点击前的渲染。然后,如果点击处理程序检测到 mascota 错误:

    setErrors({ ...errors, mascota: true });
    

    将产生一个具有所有 false 属性的对象,mascota 除外,其属性为 true。

    接下来,如果还有propietario 错误,将运行以下命令:

    setErrors({ ...errors, propietario: true });
    

    将状态设置为初始错误对象(包含所有false 值),并结合propietario 中的单个true 属性。新状态下的mascota 属性将是false,因为被引用的errors 对象包含mascota: false,并且它与propietario: true 合并。以此类推。

    您需要回调表单,以便可以正确计算新状态即使它只是由setErrors 的先前同步调用更新,否则那些先前的同步调用将不会影响新状态。

    除了所有这些手动验证之外,您还可以考虑将required 属性添加到输入中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-05
      相关资源
      最近更新 更多