Note:
Using plain React to handle complex forms doesn't scale well.
- use formik (recommended by React), or other form library
Single Item Form
import React, { ChangeEvent, FC, useState } from 'react'
export const SimpleInput: FC = () => {
const [value, setValue] = useState('default value')
const onChange = (event: ChangeEvent<HTMLInputElement>) => {
setValue(event.target.value)
}
return (
<div>
<label>
simple input
<input type="text" value={value} onChange={onChange} />
</label>
<pre>{value}</pre>
<button type="button" onClick={() => setValue('new value')}>
change to `new value`
</button>
</div>
)
}
export default <SimpleInput />
Multiple items form
import React, { FC, useState } from 'react'
import { UserAPI } from './user-api'
export const SimpleForm: FC = () => {
const [username, setUsername] = useState('')
const [password, setPassword] = useState('')
const [terms, setTerms] = useState(false)
const [submitted, setSubmitted] = useState(false)
return (
<form
aria-label="registration form"
onSubmit={async (event) => {
event.preventDefault()
setSubmitted(true)
try {
await UserAPI.register({ username, password })
// redirect to profile
} catch {
// show error
}
}}
>
<div>
<label>
Username
<input
type="text"
name="username"
value={username}
onChange={(event) => setUsername(event.target.value)}
/>
</label>
</div>
<div>
<label>
Password
<input
type="password"
name="password"
value={password}
onChange={(event) => setPassword(event.target.value)}
/>
</label>
</div>
<div>
<label>
<input
type="checkbox"
name="terms"
checked={terms}
onChange={(event) => setTerms(event.target.checked)}
/>
<span>I have read the Terms and Conditions</span>
</label>
</div>
<button type="submit">Register</button>
<pre>
{JSON.stringify({ username, password, terms, submitted }, null, ' ')}
</pre>
</form>
)
}
export default <SimpleForm />
Focusing on an form element
const ref = useRef()
const MyForm = () = {
const whatEver = () => {
ref.current.focus()
}
return (
<input ref={ref} />
)
}