2

I have a form with a handle function attached to it.

The handle function has a timeout and this is causing some problems.

 const timeOut = useRef(null);





const handleSearchChange = (e) => {
    // setSearchKey(e.target.value.toLowerCase().trim());

        clearTimeout(timeOut.current);
        timeOut.current = setTimeout(() => {
            setSearchKey(e.target.value.toLowerCase().trim());
        }, 500);
}

enter image description here

If I console.log(e.target.value) outside the settimeout function it works fine, when i incorporate the setTimeout function it breaks. Why is this?

I tried simplifying the function to just this :

const handleSearchChange = (e) => {
    // setSearchKey(e.target.value.toLowerCase().trim());
    console.log(e.target.value)
    setTimeout(() => {
        // setSearchKey(e.target.value.toLowerCase().trim());
        console.log(e.target.value)
    }, 500);
}

The issue stays..It logs the first console.log and at the second it breaks.

2 Answers 2

4

Event values are cleared by react. You either need to use event.persist to persit event values or store the values from event to be used later

According to react documentation:

SyntheticEvent object will be reused and all properties will be nullified after the event callback has been invoked. This is for performance reasons. As such, you cannot access the event in an asynchronous way.

const handleSearchChange = (e) => {
    // setSearchKey(e.target.value.toLowerCase().trim());
        clearTimeout(timeOut.current);
        const value = e.target.value.toLowerCase().trim();
        timeOut.current = setTimeout(() => {
            setSearchKey(value);
        }, 500);
}
Sign up to request clarification or add additional context in comments.

1 Comment

Awesome , I didnt know this. Thank you :)
2

That’s because the e event object in react is a synthetic event object produced by react, not the native event object produced by browser internal.

In order to prevent allocation of new objects all the time, it’s designed to be a reusable object, which means its properties are stripped after emission and re-assigned for next event.

So for your case, because you revisited this object in async callback after emission, it’s been "recycled", making it’s properties outdated. To solve this problem, you can save up beforehand the desired value in the sync event loop, then pass it to async callback.

handleSearchChange = (e) => {
    const value = e.target.value.toLowerCase().trim()

    clearTimeout(timeOut.current);
    timeOut.current = setTimeout(() => {
        setSearchKey(value);
    }, 500);
}

1 Comment

Oops, looks I’m a bit late : P

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.