30 Days of React: Day 12 | Forms
- only functional components are used hereafter
- started using a callback function approach to change the state rather than a direct approach which can sometimes leave the state to be incorrectly updated.
note: in cases where values to be updated are buried deep within the state object, a snapshot approach is used. see example below found in SignUpForm.jsconst handleChange = (e) => { const { name, value, type, checked } = e.target if (type === 'checkbox') { /** process * deep copy prev to snapshot, * change needed property in snapshot * combine prev and snapshot object, essentially snapshot replaces prev */ setData(prev => { const snapshot = { ...prev } snapshot[name][value] = checked return { ...prev, ...snapshot } }) /* Make sure to include return to prevent reaching default setData() */ return } setData(prev => ({ ...prev, [name]: value })) }
- shared components folder
- Fieldset.js - contains a map that direct
props
(using switch statement) to the appropriate Reusable Input component - Inputs.js - contains different custom input-type components:
- text
- radio-group > radio
- checkbox-group > checkbox
- date
- select w/ options
- password
- Fieldset.js - contains a map that direct
- services > userServices
- Level 1 Q&A fetched from level1qna.json
- countries fetched from https://restcountries.com/v3.1/all
- utils folder addition
- customValidation.js for validating inputs:
- name format
- email address format
- username format
- password and re-typed password match
- customValidation.js for validating inputs:
- Controlled and Uncontrolled inputs
Note: select elements are not considered as input elements hence it is not included here; tested inonBlur
event handler using:console.log(e.target.name, e.target._wrapperState.controlled) // result: country undefined
- Controlled inputs:
- firstName
- lastName
- userName
- Uncontrolled inputs:
- gender (radio)
- dob
- plan (radio)
- notifications (checkbox)
- passwords
- Controlled inputs:
-
noValidate
on form element removes the effect ofrequired
attribute in enclosed input elementsonSubmit
. -
selected
attribute inoption
is not advised, encountered warning below:Warning: Use the `defaultValue` or `value` props on <select> instead of setting `selected` on <option>.
while using code below:
<option selected disabled > Select validation type </option>
fixed using:
<select defaultValue='default' > <option value='default' disabled > Select validation type </option> {<!-- other options here -->} </select>
required
attribute in at least oneinput[type=radio]
will apply to the entire radio group (under same name)
-
Folder structure and file naming for better location/depth awareness of file or folder being worked on.
Leading underscore/s (
_
) in name- file: if file only contains sub component/s then it is named with one leading
_
(eg._components.js
) - folder: number of leading (
_
) depends on the level the folder is located relative to src files/folders
- file: if file only contains sub component/s then it is named with one leading
src/
:- Level1/
:- Level2/
: ├─ _Level2Custom/
: │ └─ __SignUpForm/
: │ ├─ _FormSections.js
: │ └─ SignUpForm.js
: ├─ _Level2Validator/
: ├─ Level2.css
: └─ Level2.js
:- services/
:- shared/
:- utils/
:- App.js
:- index.js
:- reset.css
- validator - advised by source material to validate form input values
npm i validator
- fakefiller - browser extension that fills form inputs automatically; making form testing faster
- Rest Countries API: https://restcountries.com/v3.1/all