首页 > 解决方案 > 使用功能组件创建 React 表单时出错

问题描述

今天我只是想用功能组件和使用 React 的 useState 钩子创建一个用于登录/注册的表单。但是,我遇到了这个问题。如果有人可以提供帮助,将不胜感激。我试图寻找一个原因,然而,它无济于事。谢谢。

function Login(){
   const [state, setState] = useState({
       email:'',
       password:'',
   })

   const handleChange = e => {
       setState({ [e.target.name]: e.target.value })
   } 

   const handleSubmit = e => {
       e.preventDefault();
       var email = state.email;
       var password = state.password;

       // Firebase requires passwords to be of length 6 or above
       if (password.length < 6) {
           alert("Password must of length 6 or more.");
       } else {
           fire.auth().createUserWithEmailAndPassword(email, password); 
           
           alert("Signed Up Successfully!");
       }
   }

   return(
       <>
       <Navbar/>
       <div>
           <form>
               <input name="email" value={state.email} onChange={handleChange} placeholder="email"></input>
               <input name="password" value={state.password} onChange={handleChange} placeholder="password"></input>
               <button type="submit" onClick={handleSubmit}>Sign Up!</button>
               <button type="submit">Login!</button>
           </form>
       </div>
       </>
   );
}

标签: javascriptreactjs

解决方案


useState钩子中,旧状态和传递给setState函数的对象不会像setState类组件那样自动合并。在这里,您需要确保在调用时存在所有setState状态属性以及状态的更新属性。

否则,您传递给 的setState对象将替换当前状态的对象。

您的状态有两个属性:

{
   email:'',
   password:'',
} 

但是,当您在 中更新状态时,handleChange您会省略一个状态属性。与缺少的属性关联的输入从受控组件变为不受控组件,因此您会收到错误:

const handleChange = e => {
   setState({ [e.target.name]: e.target.value })
} 

您需要将旧状态与更新的属性合并:

const handleChange = e => {
   setState({ ...state, [e.target.name]: e.target.value })
} 

或者将状态拆分为两个useState调用,每个属性调用一个:

const [email, setEmail] = useState('');
const [password, setPassword] = useState('');

然后让处理程序为每个更新:

const handleEmailChange = e => {
  setEmail({ [e.target.name]: e.target.value })
}

const handlePasswordChange = e => {
  setPassword({ [e.target.name]: e.target.value })
}

推荐阅读