Цель:
Подписаться на колесо мыши event
один раз при монтировании компонента.
Обновление state.scrollTop компонента с newValue
, где:
newValue = Math.max(0, state.scrollTop + event.deltaY)
Держите ловушки реагирования счастливыми без отключения правил по умолчанию.
Код:
const [ state, setState ] = useState({ scrollTop: 0 });
useEffect(function subscribeToWheelEvent() {
const updateScroll = function(e) {
if(!!e.deltaY) {
const delta = Math.sign(e.deltaY) * 10.0;
const val = Math.max(0, state.scrollTop + delta);
console.log(delta, val);
setState({ scrollTop: val })
} else {
console.log('zero', e.deltaY);
}
}
window.addEventListener('mousewheel', updateScroll);
console.log('subscribed to wheelEvent')
return function () {
window.removeEventListener('mousewheel', updateScroll);
}
}, []);
Ожидаемый результат:
Значение state.scrollTop
обновляет каждое событие колеса мыши на + -10 в зависимости от направления прокрутки и ограничивается 0, если newValue
меньше 0.
Текущий результат:
Значение state.scrollTop
не обновляется должным образом, переключается между 0 и 10, возможно, потому что оно запоминается внутри updateScroll
и остается на 0.
Линтер сообщает мне, что Я должен включить state.scrollTop в качестве зависимости эффекта, но я не хочу этого, так как он должен выполняться только один раз при монтировании компонента.
Следование за линтером приводит к бесконечности l oop.
В качестве альтернативы, перемещение updateScroll
за пределы функции подписки, затем в соответствии с предложениями линтера, добавление updateScroll
к зависимостям и (снова после обертывание линтера updateScroll
с useCallback(updateScroll, [state.scrollTop] )
приводит к подписке / отмене подписки на событие колеса при каждом изменении scrollTop
.
Альтернативный код:
const [ state, setState ] = useState({ scrollTop: 0 });
const updateScroll = useCallback(function(e) {
if(!!e.deltaY) {
const delta = Math.sign(e.deltaY) * 10.0;
const val = Math.max(0, state.scrollTop + delta);
console.log(delta, val );
setState({ scrollTop: val })
} else {
console.log('zero', e.deltaY);
}
}, [ state.scrollTop ])
useEffect(function subscribeToWheelEvent() {
window.addEventListener('mousewheel', updateScroll);
console.log('subscribed to wheelEvent')
return function () {
window.removeEventListener('mousewheel', updateScroll);
console.log('unsubscribed to wheelEvent')
}
}, [ updateScroll ]);
Вопрос:
Как достичь цели?