【问题标题】:How can i stop input elements from switching to from uncontrolled to controlled and vice versa using react hooks?如何使用反应钩子阻止输入元素从不受控切换到受控,反之亦然?
【发布时间】:2020-07-27 08:05:21
【问题描述】:

大家好,我在使用 React 钩子验证表单时遇到了一点问题。每当我单击显示

的提交按钮时,我都会收到错误消息

index.js:1 警告:组件正在将电子邮件类型的受控输入更改为不受控制。输入元素不应从受控切换到不受控(反之亦然)。决定在组件的生命周期内使用受控输入元素还是不受控输入元素。

这是我的代码。

    const [formData, setFormData] = useState({
  email:'',
  password:'',
  emailError:'',
  passwordError:''
 }) 



 const handleEmailChange = e => setFormData({email: e.target.value})

 const handlePasswordChange = e => setFormData({password: e.target.value})

 //validate
 const validate = () => {
  let inputError = false
  const errors = {
   emailError:'',
   passwordError:''
  }
  if(!formData.email) {
   inputError = true
   errors.emailError = 'Please enter a valid email'
  } 
  else if(!formData.email.match(emailRegex)) 
  {
   inputError = true
   errors.emailError = (
    <span style={{color:'red'}}>Your email address must be valid</span>
   )
  }

  if(formData.password.length < 4){ 
   inputError = true
   errors.passwordError = 'Your password must contain more than 4 characters'
  }

  setFormData({
   ...errors
  })

  return inputError
 }

 const onSubmit = e => {
  e.preventDefault();

  const err = validate();

  if(!err){`
   setFormData(formData)
  }
 }

我的 JSX

   <FormContainer>
   <div className="form-container">
    <form >
     <h1>Sign in</h1>
     <div className="input-container">
      <input className={formData.emailError ? 'input-error input-empty' : 'input-empty'}
       value={formData.email} 
       type="email"
        required
        onChange={e => handleEmailChange(e)}
        />
      <label>Email or Phone Number</label>
      <span style={{color: '#db7302'}}>{formData.emailError}</span>
     </div>
     <div className="input-container">
      <input 
      className={formData.passwordError ? 'input-error input-empty' : 'input-empty'}
       type="password" 
       value={formData.password} 
       required
       onChange={e => handlePasswordChange(e)}
       />
      <label>Password</label>
      <span style={{color: '#db7302'}}>{formData.passwordError}</span>
     </div>
     <div className="input-container">
      <Button href="/" onClick={e => onSubmit(e)} type="submit">Sign in</Button>
     </div>
     <label className="checkbox-container">
      Remember me
     <input type="checkbox" checked />
      <span className="checkmark"></span>
     </label>
     <Link to="/" className="need-help">Need Help?</Link>
     <div className="bottom-form">
      <img src={fbLogo} alt="" />
      <Link to="/" className="login-fb">
       Login with facebook
     </Link>
     <br/>
     <br/>
     <span style={{color:'#999'}}>New to netflix?</span>&nbsp;
     <Link to="/" className="signup-txt">Sign up now</Link>
     </div>
    </form>
   </div>
  </FormContainer>

【问题讨论】:

    标签: javascript reactjs react-hooks react-hook-form


    【解决方案1】:

    当你设置 formData 时,你不会包含所有值,所以不是将 email 作为一个空字符串,而是将它变为 undefined,并且 React 决定 input 是不受控制的,如果它是值为undefined

    为防止这种情况,请在设置 formData 时包含表单的先前值:

    setFormData(formData => ({
      ...formData,
      ...errors
    }))
    

    【讨论】:

    • 您好,感谢您的快速回复。我很感激。但是,在我这样做之后,我收到一个错误,上面写着“无法读取未定义长度的属性”和“一个组件正在将密码类型的受控输入更改为不受控制。”对于我单击提交按钮后的密码。这可能是什么原因?再次感谢您。
    • 您需要更改所有使用 setFormData 的位置以包含以前的值 - handleEmailChangehandlePasswordChange 等...我在您的代码中看不到任何数组,所以我真的不知道"cannot read property of length of undefined" 来自哪里。
    • 非常感谢您的意见。
    猜你喜欢
    • 2020-07-08
    • 2017-09-27
    • 2020-08-27
    • 2016-08-03
    • 2019-05-07
    • 2020-11-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-28
    相关资源
    最近更新 更多