Add throttling of autofill API calls

This commit is contained in:
Maciej Ziarkowski 2020-01-07 18:26:23 +00:00
parent fa31ffc198
commit b5131d12a3
2 changed files with 27 additions and 1 deletions

View File

@ -3,6 +3,7 @@ import React, { useEffect, useState } from 'react';
import './autofillDropdown.css'; import './autofillDropdown.css';
import { apiGet } from '../../../apiHelpers'; import { apiGet } from '../../../apiHelpers';
import { useThrottledValue } from '../../../hooks/useThrottledValue';
interface AutofillDropdownProps { interface AutofillDropdownProps {
fieldName: string; fieldName: string;
@ -21,6 +22,9 @@ interface AutofillOption {
export const AutofillDropdown: React.FC<AutofillDropdownProps> = props => { export const AutofillDropdown: React.FC<AutofillDropdownProps> = props => {
const [options, setOptions] = useState<AutofillOption[]>(null); const [options, setOptions] = useState<AutofillOption[]>(null);
// use both throttled and debounced field value as trigger for update
const throttledFieldValue = useThrottledValue(props.fieldValue, 1000);
useEffect(() => { useEffect(() => {
const doAsync = async () => { const doAsync = async () => {
if (!props.editing || props.fieldValue === '') return setOptions(null); if (!props.editing || props.fieldValue === '') return setOptions(null);
@ -34,7 +38,7 @@ export const AutofillDropdown: React.FC<AutofillDropdownProps> = props => {
}; };
doAsync(); doAsync();
}, [props.editing, props.fieldName, props.fieldValue]); }, [props.editing, props.fieldName, throttledFieldValue]);
if (!props.editing || options == undefined) return null; if (!props.editing || options == undefined) return null;

View File

@ -0,0 +1,22 @@
import { useEffect, useRef, useState } from 'react';
export function useThrottledValue<V>(value: V, delay: number): V {
const [throttledValue, setThrottledValue] = useState(value);
let lastUpdated = useRef(Date.now());
useEffect(() => {
const timer = setTimeout(() => {
if(Date.now() - lastUpdated.current >= delay) {
setThrottledValue(value);
console.log('Updating to', value);
lastUpdated.current = Date.now();
}
}, delay - (Date.now() - lastUpdated.current));
return () => {
clearTimeout(timer);
};
}, [delay, value]);
return throttledValue;
}