nico
nico

Reputation: 413

Why event.target.value is not updated after running await?

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

Answers (1)

Kian
Kian

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

Related Questions