![]()
In React, when handling events like onChange or onClick, the SyntheticEvent object is pooled for performance reasons—meaning it gets nullified after the event handler finishes. If you try to access event.target.value asynchronously (e.g., inside a setTimeout, Promise, or async/await), you’ll get an error like:
Cannot read property 'value' of null
Solutions:
1. Store event.target.value synchronously
Extract the value before the async operation:
const handleChange = async (event) => {
const value = event.target.value; // ✅ Store synchronously
await fetchData(value); // Safe to use later
};
2. Use event.persist() (Legacy React ≤16)
For older React versions, you could explicitly keep the event:
const handleChange = (event) => {
event.persist(); // ⚠️ Prevents nullification (not needed in React 17+)
setTimeout(() => {
console.log(event.target.value); // Works
}, 1000);
};
(Note: event.persist() is unnecessary in React 17+ since event pooling was removed.)
3. Use a ref (if dealing with forms)
If you need the latest value after an async call, consider using a ref:
const inputRef = useRef();
const handleChange = async () => {
const value = inputRef.current.value; // Always up-to-date
await fetchData(value);
};
return <input ref={inputRef} onChange={handleChange} />;
4. Use useState for controlled components
For forms, it’s better to manage state reactively:
const [inputValue, setInputValue] = useState('');
const handleChange = (event) => {
setInputValue(event.target.value); // Store in state
};
const handleSubmit = async () => {
await fetchData(inputValue); // Uses latest state
};
return <input value={inputValue} onChange={handleChange} />;
Why Does This Happen?
- React ≤16: Used event pooling (reusing event objects for performance).
- React 17+: No longer pools events, but async operations can still lead to race conditions if the DOM changes.
Best Practice
✅ For forms: Use controlled components (useState + onChange).
✅ For async ops: Extract values synchronously before await.
✅ For refs: Use useRef if you need direct DOM access.
