Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save killshot13/3470714bba8a5d4ec2c6f752777359d4 to your computer and use it in GitHub Desktop.
Save killshot13/3470714bba8a5d4ec2c6f752777359d4 to your computer and use it in GitHub Desktop.
React Forms: Controlled vs. Uncontrolled Components w/ Examples
// @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>
)
}
// @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
// @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