我正在努力学习react hooks
。这是一个注册形式,当使用具有内部状态和受控形式的经典类组件时,它工作得很好。但当我尝试像这样使用react hooks
并在输入上键入时,它将不会显示我正在键入的内容。
我已经记录了该事件,并意识到问题可能是目标值为null。有人能向我解释一下为什么会出现这种情况吗?
const SignUp = props => {
const [displayName, setDisplayName] = useState("");
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [confirmPassword, setConfirmPassword] = useState("");
const handleChange = e => {
console.log(e);
const { name, value } = e.target;
switch (name) {
case name === "displayName":
setDisplayName(value);
case name === "email":
setEmail(value);
case name === "password":
setPassword(value);
case name === "confirmPassword":
setConfirmPassword(value);
}
};
const handleSubmit = async e => {
console.log(e);
e.preventDefault();
if (password !== confirmPassword) {
alert("passwords do not match");
return;
}
const { signUpStart } = props;
signUpStart({ email, password, displayName });
};
return (
<div className="sign-up-section">
<form onSubmit={handleSubmit}>
<FormInput
type="text"
name="displayName"
handleChange={handleChange}
value={displayName}
label="display name"
/>
<FormInput
type="email"
required
name="email"
value={email}
handleChange={handleChange}
label="email"
/>
<FormInput
type="password"
name="password"
handleChange={handleChange}
value={password}
label="password"
/>
<FormInput
type="psssword"
name="confirmPassword"
handleChange={handleChange}
value={confirmPassword}
label="comfirmPassword"
/>
<Button type="submit" name="password" label="SIGN" />
</form>
</div>
);
};
const FormInput =({label,handleChange, ...otherProps})=>{
return <div className='group'>
<input {...otherProps} onChange={handleChange} className='form-input'/>
{
label?(<label className={`${otherProps.value.length? 'shrink':''} form-input-label` }>{label}</label>):null
}
</div>
}
https://stackblitz.com/edit/react-form-hooks您希望为输入字段上的每个更改设置State,因此只要输入字段发生更改,就会调用onChange回调函数。
对于回调函数,开关的情况应该是这样的:
switch(cond){
case 'cond1':
execute;
break;
}
您是否尝试过使用e.currentTarget
?
const { name, value } = e.currentTarget;
这将确保您将获得事件侦听器所附加的元素。
请参阅:javascript 中currentTarget属性和target属性之间的确切区别是什么
如下所示,问题不在于e.target
为null或未定义。实际上问题出在switch语句中。
您在这里混合了switch
和if else
的语法case name === "displayName":
。开关自动完成name ==
部分。在您的情况下,您所需要做的就是输入name
应该等于的值,而不是整个表达式。
更改如下所示,使用正确的case
和状态更新后的break
。
const {useState, useEffect} = React;
const SignUp = props => {
const [displayName, setDisplayName] = useState("");
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [confirmPassword, setConfirmPassword] = useState("");
const handleChange = e => {
console.log(e.target.name); // Logs correctly
console.log(e.target.value); // Logs correctly
const { name, value } = e.target;
switch (name) {
case "displayName":
setDisplayName(value);
break;
case "email":
setEmail(value);
break;
case "password":
setPassword(value);
break;
case "confirmPassword":
setConfirmPassword(value);
break;
}
};
const handleSubmit = e => {
console.log(e);
e.preventDefault();
if (password !== confirmPassword) {
alert("passwords do not match");
return;
}
const { signUpStart } = props;
//signUpStart({ email, password, displayName });
};
return (
<div>
<form onSubmit={handleSubmit}>
<FormInput
type="text"
name="displayName"
handleChange={handleChange}
value={displayName}
label="display name"
/>
<FormInput
type="email"
required
name="email"
value={email}
handleChange={handleChange}
label="email"
/>
<FormInput
type="password"
name="password"
handleChange={handleChange}
value={password}
label="password"
/>
<FormInput
type="psssword"
name="confirmPassword"
handleChange={handleChange}
value={confirmPassword}
label="comfirmPassword"
/>
<button type="submit" name="password">Sign</button>
</form>
</div>
);
};
const FormInput = ({label,handleChange, ...otherProps}) => {
return (
<div>
<input
{...otherProps}
onChange={handleChange}
className='form-input'
/>
{label ?
<label>{label}</label>
: null}
</div>
);
}
ReactDOM.render(<SignUp />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>