Last active
July 2, 2023 20:41
-
-
Save killshot13/3470714bba8a5d4ec2c6f752777359d4 to your computer and use it in GitHub Desktop.
React Forms: Controlled vs. Uncontrolled Components w/ Examples
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @ts-nocheck | |
import axios from 'axios' | |
import React, { useReducer, useState } from 'react' | |
const formReducer = (state, event) => { | |
if (event.reset) { | |
return { | |
name: '', | |
email: '', | |
tel: '', | |
message: '', | |
} | |
} | |
return { | |
...state, | |
[event.name]: event.value, | |
} | |
} | |
export default function ReactFormControlledFinal() { | |
const [formData, setFormData] = useReducer(formReducer, {}) | |
const [sending, setSending] = useState(false) | |
const [delivered, setDelivered] = useState(false) | |
const [failed, setFailed] = useState(false) | |
const handleSubmit = async (event) => { | |
try { | |
event.preventDefault() | |
setSending(true) | |
console.log(formData) | |
const { response } = await axios({ | |
method: 'post', | |
url: '/api/mailserver', | |
data: formData, | |
}) | |
if (response) setDelivered(true) | |
} catch (error) { | |
setFailed(true) | |
} finally { | |
setTimeout(() => { | |
setSending(false) | |
setFormData({ | |
reset: true, | |
}) | |
}, 3000) | |
} | |
} | |
const handleChange = (event) => { | |
setFormData({ | |
name: event.target.name, | |
value: event.target.value, | |
}) | |
} | |
const handleClose = (event, reason) => { | |
if (reason === 'clickaway') { | |
return | |
} | |
setDelivered(false) | |
setFailed(false) | |
} | |
return ( | |
<div> | |
<h3> | |
Once you have completed the form, | |
<br /> a specialist will contact you. | |
</h3> | |
<form onSubmit={handleSubmit}> | |
<fieldset disabled={sending}> | |
<label> | |
<span>:bust_in_silhouette:</span> | |
<p>Name</p> | |
<input | |
required | |
type='text' | |
name='name' | |
placeholder='John Doe' | |
onChange={handleChange} | |
value={formData.name || ''} | |
/> | |
</label> | |
<label> | |
<span>:email:</span> | |
<p>Email</p> | |
<input | |
required | |
type='email' | |
name='email' | |
placeholder='johndoe@aol.com' | |
onChange={handleChange} | |
value={formData.email || ''} | |
/> | |
</label> | |
<label> | |
<span>:telephone:</span> | |
<p>Phone</p> | |
<input | |
required | |
type='tel' | |
name='tel' | |
label='☎️' | |
placeholder='555-867-5309' | |
onChange={handleChange} | |
value={formData.tel || ''} | |
/> | |
</label> | |
</fieldset> | |
<fieldset disabled={sending}> | |
<label> | |
<span>:pencil:</span> | |
<p>Message</p> | |
<input | |
type='textarea' | |
name='message' | |
placeholder='[Optional]: How Can We Help?' | |
onChange={handleChange} | |
value={formData.message || ''} | |
/> | |
</label> | |
</fieldset> | |
<button type='submit' disabled={sending}> | |
{sending ? <p>Sending...</p> : <p>Submit</p>} | |
</button> | |
{alert && ( | |
<div open={delivered} autoHideDuration={6000} onClose={handleClose}> | |
<p>Your message was sent successfully!</p> | |
<button onClick={handleClose}> | |
<p>X</p> | |
</button> | |
</div> | |
)} | |
{alert && ( | |
<div open={failed} autoHideDuration={6000} onClose={handleClose}> | |
<p>Something went wrong!</p> | |
<button onClick={handleClose}> | |
<p>X</p> | |
</button> | |
</div> | |
)} | |
</form> | |
</div> | |
) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @ts-nocheck | |
import React, { useReducer, useState } from 'react' | |
import './test.css' | |
const formReducer = (state, event) => { | |
if (event.reset) { | |
return { | |
'apple': '', | |
'count': 100, | |
'name': '', | |
'gift-wrap': false, | |
} | |
} | |
return { | |
...state, | |
[event.name]: event.value, | |
} | |
} | |
function ReactFormControlledComponents() { | |
const [formData, setFormData] = useReducer(formReducer, { | |
count: 100, | |
}) | |
const [submitting, setSubmitting] = useState(false) | |
const handleSubmit = (event) => { | |
event.preventDefault() | |
setSubmitting(true) | |
setTimeout(() => { | |
setSubmitting(false) | |
setFormData({ | |
reset: true, | |
}) | |
}, 3000) | |
} | |
const handleChange = (event) => { | |
const isCheckbox = event.target.type === 'checkbox' | |
setFormData({ | |
name: event.target.name, | |
value: isCheckbox ? event.target.checked : event.target.value, | |
}) | |
} | |
return ( | |
<div className='wrapper'> | |
<h1>How About Them Apples</h1> | |
{submitting && ( | |
<div> | |
You are submitting the following: | |
<ul> | |
{Object.entries(formData).map(([name, value]) => ( | |
<li key={name}> | |
<strong>{name}</strong>:{value.toString()} | |
</li> | |
))} | |
</ul> | |
</div> | |
)} | |
<form onSubmit={handleSubmit}> | |
<fieldset disabled={submitting}> | |
<label> | |
<p>Name</p>{' '} | |
</label> | |
<input name='name' onChange={handleChange} value={formData.name || ''} /> | |
</fieldset> | |
<fieldset disabled={submitting}> | |
<label> | |
<p>Apples</p> | |
</label> | |
<select name='apple' onChange={handleChange} value={formData.apple || ''}> | |
<option value=''>--Please choose an option--</option> | |
<option value='fuji'>Fuji</option> | |
<option value='jonathan'>Jonathan</option> | |
<option value='honey-crisp'>Honey Crisp</option> | |
</select> | |
<label> | |
<p>Count</p> | |
</label> | |
<input | |
type='number' | |
name='count' | |
onChange={handleChange} | |
step='1' | |
value={formData.count || ''} | |
/> | |
<label> | |
<p>Gift Wrap</p> | |
</label> | |
<input | |
checked={formData['gift-wrap'] || false} | |
disabled={formData.apple !== 'fuji'} | |
name='gift-wrap' | |
onChange={handleChange} | |
type='checkbox' | |
/> | |
</fieldset> | |
<button type='submit' disabled={submitting}> | |
Submit | |
</button> | |
</form> | |
</div> | |
) | |
} | |
export default ReactFormControlledComponents |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @ts-nocheck | |
import React, { useReducer, useState } from 'react' | |
import './test.css' | |
const formReducer = (state, event) => ({ | |
...state, | |
[event.name]: event.value, | |
}) | |
function ReactFormUncontrolledComponents() { | |
const [formData, setFormData] = useReducer(formReducer, {}) | |
const [submitting, setSubmitting] = useState(false) | |
const handleSubmit = (event) => { | |
event.preventDefault() | |
setSubmitting(true) | |
setTimeout(() => { | |
setSubmitting(false) | |
}, 3000) | |
} | |
const handleChange = (event) => { | |
const isCheckbox = event.target.type === 'checkbox' | |
setFormData({ | |
name: event.target.name, | |
value: isCheckbox ? event.target.checked : event.target.value, | |
}) | |
} | |
return ( | |
<div className='wrapper'> | |
<h1>How About Them Apples</h1> | |
{submitting && ( | |
<div> | |
You are submitting the following: | |
<ul> | |
{Object.entries(formData).map(([name, value]) => ( | |
<li key={name}> | |
<strong>{name}</strong>:{value.toString()} | |
</li> | |
))} | |
</ul> | |
</div> | |
)} | |
<form onSubmit={handleSubmit}> | |
<fieldset> | |
<label htmlFor='name'> | |
<p>Name</p> | |
</label> | |
<input name='name' onChange={handleChange} /> | |
</fieldset> | |
<fieldset> | |
<label> | |
<p>Apples</p> | |
<select name='apple' onChange={handleChange}> | |
<option value=''>--Please choose an option--</option> | |
<option value='fuji'>Fuji</option> | |
<option value='jonathan'>Jonathan</option> | |
<option value='honey-crisp'>Honey Crisp</option> | |
</select> | |
</label> | |
<label> | |
<p>Count</p> | |
<input type='number' name='count' onChange={handleChange} step='1' /> | |
</label> | |
<label> | |
<p>Gift Wrap</p> | |
<input type='checkbox' name='gift-wrap' onChange={handleChange} /> | |
</label> | |
</fieldset> | |
<button type='submit'>Submit</button> | |
</form> | |
</div> | |
) | |
} | |
export default ReactFormUncontrolledComponents |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment