Event Pooling (React 16 and earlier)

How Pooling Worked

To save memory in old browsers, React 16 reused event objects from a pool. After your handler finished, React reset every property of the event to null and put it back in the pool.

// React 16
function handleChange(e) {
  console.log(e.target.value);   // ✓ works (still inside the handler)

  setTimeout(() => {
    console.log(e.target);       // ✗ null — the event was already returned to the pool
  }, 0);
}

e.persist()

Calling e.persist() removed the event from the pool so you could use it later (e.g. in async code). The usual alternative was to copy the value first.

// React 16 fixes
function handleChange(e) {
  e.persist();                       // keep the event
  setTimeout(() => console.log(e.target.value), 0);

  const value = e.target.value;      // or copy what you need
  setTimeout(() => console.log(value), 0);
}