Используя debounce для поиска в реакции
У меня есть вход для поиска, чтобы сделать вызовы API на лету. Я хотел бы реализовать debounce, чтобы уменьшить количество обращений к серверу.
_debouncedSearch() {
debounce(this.props.fetchRoutes(this.state.searchText), 1000);
}
_updateResults(searchText) {
this.setState({searchText});
this._debouncedSearch();
}
Я ожидаю debouncedSearch
каждую 1 секунду Но это все еще называется на лету. И скинуть ошибки:
Uncaught TypeError: Ожидается функция при отладке (lodash.js? 3387: 10334)
Uncaught Error: возникла перекрестная ошибка. У React нет доступа к фактическому объекту ошибки в разработке.
Я чувствую, что этот вопрос нужно задавать часто, но мне кажется, что ни одно из решений не работает. Может ли кто-нибудь объяснить мне, в чем именно проблема? Я думал, что debounce - это просто setTimeOut.
Спасибо
3 ответа
_.debounce
уже выполненная функция (функция возвращает функцию) . затем _debouncedSearch
должен быть атрибутом класса, а не методом:
_debouncedSearch= debounce(() => this.props.fetchRoutes(this.state.searchText), 1000);
вместо:
_debouncedSearch() {
debounce(this.props.fetchRoutes(this.state.searchText), 1000);
}
Кроме того, обратите внимание, первый аргумент _.debounce
это функция (() => this.props.fetchRoutes...
), а не напрямую this.props.fetchRoutes...
constructor(props) {
super(props);
this.state = {
searchText: '',
};
this._debouncedSearch = debounce(
() => this.props.fetchRoutes(this.state.searchText),
1000
);
}
_updateResults(searchText) {
this.setState({searchText});
this._debouncedSearch();
}
Вот полный рабочий код на случай, если кому-то это нужно!
Недавно нашел этот вопрос полезным. Вот мое оптимизированное решение:
const [searchTerm, setSearchTerm] = useState("");
const [result, setResult] = useState([]);
async function fetchData(searchTerm: string) {
const { data } = await client.query(searchTerm);
setResult(data);
}
const debounceLoadData = useMemo(() => debounce(fetchData, 700), []);
useEffect(() => {
window.addEventListener("keydown", debounceLoadData(searchTerm));
return () => {
window.removeEventListener("keydown", debounceLoadData(searchTerm));
};
}, [searchTerm]);
Это вызовет функцию только один раз после того, как пользователь перестанет печатать в течение 700 мс. Затем я использую
useMemo
кэшировать каждый результат. Если пользователь ищет одно и то же значение несколько раз, он вернет кэшированное значение и не вызовет
fetchData()
функционировать больше, чем необходимо.