Reputation: 413
I'm writing a onChange event handler that runs with some async codes. Since the function is asynchronous, event object has persisted at the top.
Before running await
, 'event.targe.value' is expected, but after running await, event.target.value is not updated.
I know that I can cache value like const value = event.targe.value
before running await, but I want to know why the event.target.value changes before and after await.
function MyApp() {
const [title, setTitle] = useState('')
const handleChange = async (e) => {
// if I type 'a'
console.log(e.target.value) // 'a'
e.persist()
console.log(e.target.value) // 'a'
// some async code here
await Promise.resolve(null)
console.log(e.target.value) // value is not 'a' but '', not updated
setTitle(e.target.value)
}
return <input value={title} onChnage={handleChange} />
}
Upvotes: 1
Views: 1672
Reputation: 206
Event handlers
will be passed instances of SyntheticEvent
.
The SyntheticEvent is pooled. This means that the SyntheticEvent object will be reused and all properties will be nullified after the event callback has been invoked.
If you want to access the event properties in an asynchronous way, you should call event.persist() on the event, which will remove the synthetic event from the pool and allow references to the event to be retained by user code.
-- React Docs
Using e.persist()
allows you to fetch the event.target.value
in the async function:
const handleChange = async (e) => {
e.persist()
// async function
await new Promise((resolve) => {
console.log('async', e.target.value) // you can get the value here
resolve()
})
console.log(e.target.value) // but not here
}
Also, checkout this answer here.
Upvotes: 3