Set input value with a debounced onChange handler
Asked Answered
C

1

3

In my React Hooks app I need to let user type to an input field for 1000ms. When 1000ms expire an API request is sent with the input value.

<input type='text' name='name' className='th-input-container__input' onChange={evt => testFunc2(evt.target.value)} />

The value is set in testFunc2(evt.target.value):

const testFunc2 = useCallback(debounce((text) => setNameFilter(text), 1000), []);

Once nameFilter is set to a new value useEffect issues an API request since nameFilter is its dependency. That way the API is queried with only the resulting user input instead of with each key stroke value but the input stays uncontrolled. When I add the current nameFilter value to the input with value={nameFilter} user cannot type into the input and the input receives only the last typed character.

How do I get the user typed characters to display in the input?

Carolincarolina answered 16/12, 2019 at 13:55 Comment(2)
Just curious, do you write your own debounce function or use lodash's one?Dusty
The one provided by "just-debounce-it".Carolincarolina
D
5

Updated answer:

const debouncedApiCall = useCallback(debounce((text) => {
  getRecordsForPage(1, text, '', '', '', '', 10, {});
}, 1000), [])

useEffect(() => {
  debouncedApiCall(nameFilter);
}, [nameFilter, debouncedApiCall])

<input type='text' value={nameFilter} onChange={evt => setNameFilter(evt.target.value)} />
Dusty answered 16/12, 2019 at 14:10 Comment(4)
Here's changes I applied to your solution to make it produce the desired result. Please consider adding those to the solution so I can accept it. const debouncedApiCall = useCallback(debounce((text) => getRecordsForPage(1, text, '', '', '', '', 10, {}), 1000), []);. useEffect(() => { debouncedApiCall(nameFilter); }, [nameFilter, debouncedApiCall]);. The input element code is as provided in your solution. getRecordsForPage is the API call method to send a request.Carolincarolina
Thank you for the nice and timely solution. You missed the [] dep array in useCallback in const debouncedApiCall. Please add it so the code will look correct.Carolincarolina
@ElAnonimo Sorry, I haven't used React for a while and deliberately missed it. Thank you for your correction.Dusty
Please remove , 1000 from the getRecordsForPage arguments. It's the debounce timeout value. The getRecordsForPage arguments are all listed in the first parens only.Carolincarolina

© 2022 - 2024 — McMap. All rights reserved.