- What's Difficult About Forms?
- Handling Form Submission & Validating User Input
- Using Buil-in Form Features
- Building Custom Solutions
- run
npm install
- run
npm run dev
- create a
README.md
file
- in
login.jsx
, define a newhandleSubmit
function and bind it as a value to theonSubmit
prop of the<form>
element - add the
event.preventDefault()
function to prevent the default browser behaviour when submitting the form
- access to the value entered by the user with help of
useState()
- set up some change listener
handleInputChange
function & send it as a value of theonChange
props - call the state updating functions inside of this
handleInputChange
function - feed the
event.target.value
back into the inputs by setting thevalue
props equal to the state values console.log
the state values in thehandleSubmit
function
- copy the
Login.jsx
component & name itStateLogin.jsx
to keep that code where we use state for tracking the user input - use refs instead of state
- connect those refs to the input fields
- use this connection inside of the
handleSubmit
function to get the entered email & the entered password
- add a
Signup.jsx
file to this project - output the
<Signup>
component inApp.jsx
instead of the<Login>
component - in
Signup.jsx
, add ahandleSubmit
function & connect it to theonSubmit
prop of theform
element - inside of the
handleSubmit
function, use theformData
constructor function built into the browser - as a result get back the form data object to get access to the data that was added to all the inputs in that form
- for this to work, all those inputs must have the
name
prop - use the
get()
method to extract the value of a specificname
- or even better, use the built-in
Object
class & call thefromEntries
static method of that class - pass to it the result of the result of calling the
entries
method that form data objectfd
- calling
entries()
on thefd
object will give you kind of an array of all the input fields and their values - and calling
Object.fromEntries()
on that array will give you an object where you have key value pairs for all your input fields - get back the lost multi value input fields & manually extract them & store them with the
getAll()
method - merge them into the
data
object by adding a newacquisition
property to it
- if you are managing the input with state, reset those state values (see
StateLogin.jsx
) - if you're getting the entered values with refs, reset the inputs by manually setting the value property of the connected input elements to empty strings as in
Login.jsx
(but not really recommended) - instead if you're working with refs, it's typically better to reset the form with help of the
reset()
function as inSignup.jsx
(imperative code again, but less code) - comment out the code snippets responsible for resetting the forms
- in
App.jsx
, render the<Login>
component imported from./components/StateLogin.jsx
to get the stateful version of that login form - validate the
email
input on every keystroke by adding a computed value namedemailIsInvalid
to thisStateLogin.jsx
component - set this
emailIsInvalid
constant based on the email state value which you're managing, so here we could say thatemailIsInvalid
should be true if the entered email does not include an@
symbol - update the UI by outputting an error message if this
emailIsInvalid
is true - make sure that
emailIsInvalid
is only set to true if the user did start entering a value
- in
StateLogin.jsx
, react to the email input field losing focus by adding theonBlur
event listening Prop to it - add a new
handleInputBlur
event handling function - manage a new
didEdit
state, because now, we don't just wanna keep track of the value that has been entered into an input, but we also wanna keep track of whether the user touched this value or not - update this state in the
handleInputBlur
function - trigger this
handleInputBlur
function as a value to theonBlur
prop - use this new
didEdit
state to perform validation- And we can check whether
emailIsInvalid
by not checking for whether it still has the initial valueenteredValues.email !== ''
- but by instead keeping this check
!enteredValues.email.includes('@')
and combining this check withdidEdit.email
- And we can check whether
- remove this error message as soon as the user starts typing again so that he has another chance of entering a valid value until he's done typing and the input loses focus again at which point of time this validation should run again
- in
handleInputChange
, also updatedidEdit
on every keystroke - reset the
email
&password
properties tofalse
whenever the user starts typing again
- in
- switch back from the
StateLogin.jsx
version of theLogin
form to the ref-basedLogin
form inApp.jsx
- since we wanna stick to refs, you can basically only validate the input when the user submits the form
- in the
handleSubmit
function, determine whether the email is valid, by adding theemailIsalid
constant - when the form is submitted, perform your check by checking if you don't have an
@
symbol in that email with theincludes
- in the
- reflect this error in your form with some
emailIsInvalid
state - you can also add submission-based validation in
StateLogin.jsx
even if you are already validating the user input on every keystroke because it is always a good idea
- switch back to
Signup.jsx
inApp.jsx
- add the browser built-in
required
prop to validate the inputs & form control elements - add the browser built-in
minLength
prop to thepassword
input
- make sure that the value entered in the
confirm-password
field matches the value entered into thepassword
field with help of apasswordsAreNotEqual
state - when the form is submitted before console logging the data, check if
data.password
is not equal to thedata['confirm-password']
prop & if it is true update thepasswordsAreNotEqual
state - output an error if the passwords are not equal with help of the
passwordsAreNotEqual
state
- switch back to
<StateLogin>
inApp.jsx
- add a new
Input.jsx
component file - use this
<Input>
component inStateLogin.jsx
- manage validation for password
- set an error message for email & password if not valid
- import
isEmail
,isNotEmpty
&hasMinLength
fromvalidation.js
inStateLogin.jsx
- use
isEmail
&isNotEmpty
to validate the email - use
hasMinLength
to validate the password
- add a new
hooks
folder & inside add a newuseInput.js
file - build this hook
- use this hook in
StateLogin.jsx