У меня есть функция обработчика событий, которая при каждом запуске должна очищать setTimeout()
и установите новый тайм-аут.
Теперь обратный вызов для тайм-аута должен принимать несколько аргументов, например объект события, полученный обработчиком.
Вот и все. Я сделал это, но считаю, что мое решение не оптимальное и не самое чистое:
let timer;
const handler = (event, type) => {
clearTimeout(timer);
if(type === 'CHANGE') timer = setTimeout(callback, 500, { argumentsForTheCallBack });
}
Как видите, у меня есть timer
как глобальная переменная, хотя мне она нужна только в обработчике событий.
Есть ли способ сделать обработчик автономным?
Меня интересуют решения ECMAScript, а также решения с использованием синтаксиса React.js (в моем исходном коде обратный вызов является диспетчером для useReducer
крюк)
1 ответ
Поскольку вы упоминаете useReducer
Хук React Я предполагаю, что вы используете функциональный компонент и, следовательно, можете использовать другие хуки React.
Я предлагаю:
- Используйте React ref для хранения ссылки на таймер (а не на глобальную переменную).
- Используйте
useEffect
крючок для очистки любых тайм-аутов выполнения в случае, если компонент отключится до истечения тайм-аута. Предоставьте пустой массив зависимостей, чтобы обратный вызов эффекта вызывал только один раз. Здесь просто нужно вернуть функцию очистки, чтобы очистить все тайм-ауты.
Код:
import { useEffect, useRef } from 'react';
...
// in component
const timerRef = useRef(null);
useEffect(() => {
return () => clearTimeout(timerRef.current);
}, []);
const handler = (event, type) => {
clearTimeout(timerRef.current);
if (type === 'CHANGE') {
timerRef.current = setTimeout(callback, 500, { argumentsForTheCallBack });
}
}
Зачем нужна функция очистки от useEffect
?
Если вы попытаетесь обновить состояние отключенного компонента, вы получите предупреждение React, в котором говорится:
Предупреждение: невозможно выполнить обновление состояния React для отключенного компонента. Это не работает, но указывает на утечку памяти в вашем приложении. Чтобы исправить это, отмените все подписки и асинхронные задачи в функции очистки useEffect.
Это просто предупреждение, поэтому, если вы согласны с предупреждением в непроизводственных сборках и знаете, что на самом деле у вас нет утечки памяти (открытые сокеты, соединения, подписки и т. д.), вы, вероятно, можете спокойно игнорировать их.
В общем, вы должны стремиться писать код, который не генерирует предупреждений, и это предупреждение легко предотвратить.
useEffect
с пустым массивом, поскольку зависимость должна запускаться только один раз при запуске приложения. Что мне не хватает?— Шейх Йербути
— Дрю Риз
— Дрю Риз
useEffect
выполняется только один раз в начале? Он автоматически вызывается снова, когда компонент отключается? И если да, то только ли это дляuseEffect
s с пустым массивом в качестве зависимости?— Шейх Йербути
useEffect
hook вызывается в конце начального рендеринга, а очистка эффекта будет вызвана при размонтировании компонента. Как правило, функция очистки вызывается в конце цикла визуализации перед повторной визуализацией компонента (для очистки любых эффектов от предыдущей визуализации) или при размонтировании компонента. Эффект с пустой зависимостью и возвращенной функцией очистки примерно эквивалентенcomponentDidMount
а такжеcomponentWillUnmount
методы жизненного цикла. Видеть reactjs.org/docs/hooks-reference.html#cleaning-up-an-effect.— Дрю Риз