React Forms
Form is used to take input from user
function MyForm() {
return (
<form>
<input type="text" />
</form>
)
}By default page refresh on submit
React Form vs HTML Form
HTML form handles data itself
React form uses state to handle data
Controlled Component
React controls input using state
Data is stored in state
useState with Form
import { useState } from "react"
function MyForm() {
const [name, setName] = useState("")
const handleChange = (e) => {
setName(e.target.value)
}
return (
<input
type="text"
value={name}
onChange={handleChange}
/>
)
}Show Input Value
<p>{name}</p>Initial Value
const [name, setName] = useState("John")Important Points
Use state to store input
Use onChange to update value
value comes from state
React controls form
React Submit Forms
When user clicks submit button
Form is submitted
Problem in React
By default form refreshes page
But in React we do not want page reload
Solution
Use onSubmit event and prevent default
Example
import { useState } from "react"
function MyForm() {
const [name, setName] = useState("")
const handleChange = (e) => {
setName(e.target.value)
}
const handleSubmit = (e) => {
e.preventDefault()
alert(name)
}
return (
<form onSubmit={handleSubmit}>
<input value={name} onChange={handleChange} />
<button type="submit">Submit</button>
</form>
)
}Key Points
use onSubmit in form
use preventDefault to stop refresh
handle data using state
React Textarea
HTML uses content inside textarea
React uses value attribute
function MyForm() {
const [text, setText] = useState("")
return (
<textarea
value={text}
onChange={(e) => setText(e.target.value)}
/>
)
}textarea value comes from state
onChange updates state
React Select
HTML uses selected
React uses value
function MyForm() {
const [car, setCar] = useState("Volvo")
return (
<select value={car} onChange={(e) => setCar(e.target.value)}>
<option value="Ford">Ford</option>
<option value="Volvo">Volvo</option>
</select>
)
}select value controlled by state
onChange updates selected value
Multiple Input Fields
Problem
Many inputs need separate state
Solution
Use one state object
function MyForm() {
const [inputs, setInputs] = useState({})
const handleChange = (e) => {
const name = e.target.name
const value = e.target.value
setInputs(values => ({ ...values, [name]: value }))
}
return (
<>
<input name="firstname" onChange={handleChange} />
<input name="lastname" onChange={handleChange} />
<p>{inputs.firstname} {inputs.lastname}</p>
</>
)
}How it Works
name attribute identifies field
value comes from input
state updates using spread operator
Initial Values
const [inputs, setInputs] = useState({
firstname: "John",
lastname: "Doe"
})Checkbox
Checkbox is used to select multiple options
Use checked instead of value
function MyForm() {
const [checked, setChecked] = useState(false)
return (
<input
type="checkbox"
checked={checked}
onChange={(e) => setChecked(e.target.checked)}
/>
)
}Multiple Checkbox with Object State
function MyForm() {
const [inputs, setInputs] = useState({})
const handleChange = (e) => {
const name = e.target.name
const value = e.target.type === "checkbox"
? e.target.checked
: e.target.value
setInputs(values => ({ ...values, [name]: value }))
}
return (
<>
<input type="checkbox" name="tomato" onChange={handleChange} />
<input type="checkbox" name="onion" onChange={handleChange} />
</>
)
}Use checked for checkbox
Use e.target.checked for value
Use name to identify checkbox
Initial Values
const [inputs, setInputs] = useState({
tomato: true,
onion: false
})Radio
Radio is used to select only one option
All radio buttons must have same name
function MyForm() {
const [fruit, setFruit] = useState("banana")
return (
<>
<input
type="radio"
name="fruit"
value="apple"
checked={fruit === "apple"}
onChange={(e) => setFruit(e.target.value)}
/> Apple
<input
type="radio"
name="fruit"
value="banana"
checked={fruit === "banana"}
onChange={(e) => setFruit(e.target.value)}
/> Banana
</>
)
}Use checked to control radio
Compare state with value
Same name for all radios