I'm creating a input form for an e-mail and i have a delayed onChange on it to not call the api too many times.
Here's my code:
const InformationCollection = (props) => {
const [email, setEmail] = useState()
const [collectedEmail, setCollectedEmail] = useState(1)
useEffect(() => {
let timeout = setTimeout(() => {
setCollectedEmail(email)
console.log(collectedEmail)
}, 500)
return () => {
clearTimeout(timeout)
}
}, [email])
return (
<div className="form-group">
<label htmlFor="inputmail">Email address</label>
<input
type="email"
className="form-control"
onChange={(e) => {
setEmail(e.target.value)
console.log(e.target.value + "this is what is set" + email)
}}
aria-label="Enter e-mail address"
/>
</div>
)
}
export default InformationCollection
On this line if i type "1" console.log(e.target.value + "this is what is set" + email)
, e.target.value is 1, but email
is undefined.
On the next character "12", e.target.value is 12 but email
is 1
Can anyone help with this?
UPDATE:
The solution is to have 2 useEffectHooks. One for the value in the form email
and one for the delayed value collectedEmail
Second solution is to do fetch inside the first useEffect hook
const InformationCollection = (props) => {
const [email, setEmail] = useState()
const [collectedEmail, setCollectedEmail] = useState()
useEffect(() => {
let timeout = setTimeout(() => {
//fetch directly here
setCollectedEmail(email)
console.log(collectedEmail)
}, 500)
return () => {
clearTimeout(timeout)
}
}, [email])
useEffect(() => {
//fetch() here
console.log(collectedEmail) //right value
}, [collectedEmail])
return (
<div className="form-group">
<label htmlFor="inputmail">Email address</label>
<input
type="email"
className="form-control"
onChange={(e) => {
setEmail(e.target.value)
console.log(e.target.value + "this is what is set" + email)
}}
aria-label="Enter e-mail address"
/>
</div>
)
}
export default InformationCollection
state is updated asynchronously, that's why email
is undefined for the first time when you try to log it after updating the state.
You can log the email inside useEffect
hook which will be called after email has changed.
On the next character "12", e.target.value is 12 but email is 1
email
is 1
because when onChange
event fired for the first time, email
was undefined but when onChange
event fires for the second time, email
had already been updated asynchronously to 1