Reputation: 159
I'm trying to study react hooks
. this is a sign-up form that works well when using the classical class component with internal state and controlled forms. but when I try to use react hooks
like this and type on the input it just will not display what I'm typing.
I have logged the event and have realized that the problem could be that the target value is null. Can somebody explain to me why this could be the case?
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>
}
Upvotes: 1
Views: 8622
Reputation: 14355
As you can see below, the problem isn't that e.target
is null or undefined. The problem is actually in your switch statement.
You're blending syntax of switch
and if else
here case name === "displayName":
. The switch automatically does the name ==
part. In your case, all you need to do is put what name
should be equal to - not the whole expression.
Change as shown below, with correct case
's and with break
's after the state update.
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>
Upvotes: 0
Reputation: 7305
Have you tried using e.currentTarget
instead?
const { name, value } = e.currentTarget;
That will ensure that you will get the element to which the event listener is attached.
See: What is the exact difference between currentTarget property and target property in javascript
Upvotes: 1
Reputation: 761
https://stackblitz.com/edit/react-form-hooks you want to setState for each change on the input field, so the onChange callback function will be called whenever there is a change to the input field.
coming to your callback function, the switch case should be like this:
switch(cond){
case 'cond1':
execute;
break;
}
Upvotes: 1