Reputation: 3
I'm experiencing some crazy graphical glitches on my react app, specifically when I scroll elements into view.
Quick overview - the app is a portrait kiosk app where every 'stage' element is like a card filling up the whole screen, and as the user progresses the app's flow, cards scroll horizontally to the left or right (based on language), bringing the newest stage's card into view, and deleting the previous one when the scroll finishes.
Well ever since the chrome update a few days ago, things are barely working. Some stage are snapped back into when the current scroll ends, elements from different stages will suddenly appear at random positions on the screen over other stages, and sometimes parts of a stage will not render properly, as if cut in half at an arbitrary position. Also on some stages, the onScrollComplete won't be called at all.
This is 10 times worse when I test the application using chrome's device simulator, 100 time worse when I do so with throttling.
I'm suspecting the chrome version itself, because other app are experiencing strange behaviors as well - such as chrome tab crashing ("oh snap" screen) if I log into and account using auth0 while the developer tools are opened, or the dev tools screen crashing when reloading the page after certain event, stuff like that.
Anyway,this is the relevant code:
Scrolling mechanism:
const stageElement = stageRefs.current[currentStage?.name].current
if (!stageElement) {
console.error(`Stage ${currentStage?.name} was not found in the DOM`)
return
}
if (!scrolling) {
setScrolling(true)
stageElement.focus()
stageElement.scrollIntoView({
behavior: 'smooth',
block: 'start',
inline: 'start'
})
}
On scroll complete hook:
import { useEffect, useRef } from 'react';
const useScrollCompletion = (scrollerRef, onComplete) => {
const scrollEndTimer = useRef(null);
useEffect(() => {
const handleScroll = () => {
clearTimeout(scrollEndTimer.current);
scrollEndTimer.current = setTimeout(() => {
console.log('scroll complete')
onComplete();
}, 150);
};
const scrollerElement = scrollerRef.current;
if (scrollerElement) {
scrollerElement.addEventListener('scroll', handleScroll);
}
return () => {
if (scrollerElement) {
scrollerElement.removeEventListener('scroll', handleScroll);
}
clearTimeout(scrollEndTimer.current);
};
}, [scrollerRef, onComplete]);
};
export default useScrollCompletion;
Callbak used when scrolling is completed:
const onScrollComplete = () => {
setScrolling(false)
if (activeStages.some(stage => stage.name !== 'home')) {
clearStages()
}
if (currentStage?.name === 'home' && activeStages.some(stage => stage.name !== 'home')) {
clearStages()
}
}
(activeStages is a map representing currently mounted JSX objects.)
Thanks!
Oh and p.s -
Firefox works marvelously
Upvotes: 0
Views: 24