I am building page where user can switch between login and signup mode by clicking the switch button. Login form has 2 input fields and signup form has 3 input fields. My thinking was to build 2 separate forms independent from each other and use 2 separate custom hook instances.
import React, { useState } from "react";
import { useForm } from "../../shared/hooks/form-hook";
import Card from "../../shared/ponents/UIElements/Card";
import Input from "../../shared/ponents/FormElements/Input";
import Button from "../../shared/ponents/FormElements/Button";
import {
VALIDATOR_MINLENGTH,
VALIDATOR_EMAIL
} from "../../shared/util/validators";
import "./Auth.css";
const Auth = props => {
const [showLogin, setShowLogin] = useState(true);
const [formStateLogin, inputHandlerLogin] = useForm(
{
email: {
value: "",
isValid: false
},
password: {
value: "",
isValid: false
}
},
false
);
const [formStateSignup, inputHandlerSignup] = useForm(
{
name: {
value: "",
isValid: false
},
email: {
value: "",
isValid: false
},
password: {
value: "",
isValid: false
}
},
false
);
const loginSubmitHandler = event => {
event.preventDefault();
console.log("login handler");
};
const signupSubmitHandler = event => {
event.preventDefault();
console.log(formStateSignup.inputs);
};
const switchButtonHandler = () => {
setShowLogin(!showLogin);
};
return (
<Card className="authentication">
{showLogin ? (
<form onSubmit={loginSubmitHandler} className="place-form">
<h2>Enter your login details</h2>
<Input
id="email"
element="input"
type="email"
placeholder="Email address"
label="Email"
validators={[VALIDATOR_EMAIL(), VALIDATOR_MINLENGTH(5)]}
onInput={inputHandlerLogin}
errorText="Please enter valid email address"
/>
<Input
id="password"
element="input"
type="password"
placeholder="Password"
label="Password"
validators={[VALIDATOR_MINLENGTH(5)]}
onInput={inputHandlerLogin}
errorText="Please enter valid password (at least 5 chars)"
/>
<Button type="submit" disabled={!formStateLogin.isValid}>
LOGIN
</Button>
</form>
) : (
<form onSubmit={signupSubmitHandler} className="place-form">
<h2>Enter your signup details</h2>
<Input
id="name_s"
element="input"
type="text"
placeholder="Enter your name"
label="Name"
validators={[VALIDATOR_MINLENGTH(2)]}
onInput={inputHandlerSignup}
errorText="Please enter valid name at least 2 chars"
/>
<Input
id="email_s"
element="input"
type="email"
placeholder="Email address"
label="Email"
validators={[VALIDATOR_EMAIL(), VALIDATOR_MINLENGTH(5)]}
onInput={inputHandlerSignup}
errorText="Please enter valid email address"
/>
<Input
id="password_s"
element="input"
type="password"
placeholder="Password"
label="Password"
validators={[VALIDATOR_MINLENGTH(5)]}
onInput={inputHandlerSignup}
errorText="Please enter valid password (at least 5 chars)"
/>
<Button type="submit" disabled={!formStateSignup.isValid}>
LOGIN
</Button>
</form>
)}
<Button inverse onClick={switchButtonHandler}>
{showLogin ? "SWITCH TO SIGNUP" : "SWITCH TO LOGIN"}
</Button>
</Card>
);
};
export default Auth;
Both forms seem to render fine but the trouble is when I enter text in one form and decide to switch to other form, values from departed form are not lost but rather translated to new form:
Is this limitation of ReactJS, is it HTML? :) Or is it just my buggy code?
I am building page where user can switch between login and signup mode by clicking the switch button. Login form has 2 input fields and signup form has 3 input fields. My thinking was to build 2 separate forms independent from each other and use 2 separate custom hook instances.
import React, { useState } from "react";
import { useForm } from "../../shared/hooks/form-hook";
import Card from "../../shared/ponents/UIElements/Card";
import Input from "../../shared/ponents/FormElements/Input";
import Button from "../../shared/ponents/FormElements/Button";
import {
VALIDATOR_MINLENGTH,
VALIDATOR_EMAIL
} from "../../shared/util/validators";
import "./Auth.css";
const Auth = props => {
const [showLogin, setShowLogin] = useState(true);
const [formStateLogin, inputHandlerLogin] = useForm(
{
email: {
value: "",
isValid: false
},
password: {
value: "",
isValid: false
}
},
false
);
const [formStateSignup, inputHandlerSignup] = useForm(
{
name: {
value: "",
isValid: false
},
email: {
value: "",
isValid: false
},
password: {
value: "",
isValid: false
}
},
false
);
const loginSubmitHandler = event => {
event.preventDefault();
console.log("login handler");
};
const signupSubmitHandler = event => {
event.preventDefault();
console.log(formStateSignup.inputs);
};
const switchButtonHandler = () => {
setShowLogin(!showLogin);
};
return (
<Card className="authentication">
{showLogin ? (
<form onSubmit={loginSubmitHandler} className="place-form">
<h2>Enter your login details</h2>
<Input
id="email"
element="input"
type="email"
placeholder="Email address"
label="Email"
validators={[VALIDATOR_EMAIL(), VALIDATOR_MINLENGTH(5)]}
onInput={inputHandlerLogin}
errorText="Please enter valid email address"
/>
<Input
id="password"
element="input"
type="password"
placeholder="Password"
label="Password"
validators={[VALIDATOR_MINLENGTH(5)]}
onInput={inputHandlerLogin}
errorText="Please enter valid password (at least 5 chars)"
/>
<Button type="submit" disabled={!formStateLogin.isValid}>
LOGIN
</Button>
</form>
) : (
<form onSubmit={signupSubmitHandler} className="place-form">
<h2>Enter your signup details</h2>
<Input
id="name_s"
element="input"
type="text"
placeholder="Enter your name"
label="Name"
validators={[VALIDATOR_MINLENGTH(2)]}
onInput={inputHandlerSignup}
errorText="Please enter valid name at least 2 chars"
/>
<Input
id="email_s"
element="input"
type="email"
placeholder="Email address"
label="Email"
validators={[VALIDATOR_EMAIL(), VALIDATOR_MINLENGTH(5)]}
onInput={inputHandlerSignup}
errorText="Please enter valid email address"
/>
<Input
id="password_s"
element="input"
type="password"
placeholder="Password"
label="Password"
validators={[VALIDATOR_MINLENGTH(5)]}
onInput={inputHandlerSignup}
errorText="Please enter valid password (at least 5 chars)"
/>
<Button type="submit" disabled={!formStateSignup.isValid}>
LOGIN
</Button>
</form>
)}
<Button inverse onClick={switchButtonHandler}>
{showLogin ? "SWITCH TO SIGNUP" : "SWITCH TO LOGIN"}
</Button>
</Card>
);
};
export default Auth;
Both forms seem to render fine but the trouble is when I enter text in one form and decide to switch to other form, values from departed form are not lost but rather translated to new form:
Is this limitation of ReactJS, is it HTML? :) Or is it just my buggy code?
Share Improve this question edited Jan 25, 2020 at 15:02 daniel.tosaba asked Jan 25, 2020 at 14:55 daniel.tosabadaniel.tosaba 2,5639 gold badges36 silver badges47 bronze badges 2-
2
use different names of
state
for forms it will work – Bilal Hussain Commented Jan 25, 2020 at 15:07 - Didn't I already by using separate useForm hook instance??? – daniel.tosaba Commented Jan 25, 2020 at 15:17
3 Answers
Reset to default 1It's not a good convention to have two forms in one ponent, it makes a mess...I would make rather two separated ponents of LoginForm and SignUpForm and switch between them through ternary operator based on the state
whatever way you like. Your forms and their state will be separated and code is more readable
It happens same for checkbox and radio buttons if you select radio button on first page then renders second page with radio button it will be automatically selected as dom operations are costly,
In your case react is just adding new third field and removing it you need to set the value attribute of fields to respective state.
you can actually. use the nested route to switch between ponents
import { Switch, Route } from 'react-router-dom';
<Switch>
<Route path='/register' >
// ponent 1
<Register />
</Route>
<Route path='/login' >
// ponent 2
<Login />
</Route>
</Switch>