admin管理员组文章数量:1296257
I am attempting to track the scroll progress when this element scrolls horizontally. Everything works well – except when I use the useCenterColumn
hook to adjust the size of the children within the parent element whose scroll I am tracking.
The scroll
event on the parent element stops firing completely (both the ref?.addEventListener
and the div's onScroll
stop). I've tried using useLayoutEffect
and useInsertionEffect
here but those don't seem to change anything.
What do I have to do to ensure this sliderRef
continues to fire scroll events after useCenterColumn
changes the layout?
This is a NextJS v15 app, so I'm also wondering if this is producing side effects.
import { FC, useEffect, useRef, useState } from "react";
import cx from "classnames";
import Link from "next/link";
import { BlockWrapper, Image } from "components";
import { useSliderMutate } from "contexts/SliderContext";
const Breakpoints: { [key: string]: number } = {
xs: 0,
xl: 1200,
"3xl": 1920,
};
const ContainerPadding: { [key: string]: number } = {
xs: 29,
xl: 60,
"3xl": 96,
};
const useCenterColumn = () => {
const [centerColumn, setCenterColumn] = useState(0);
useEffect(() => {
const updateCenterColumn = () => {
const vw =
typeof window !== "undefined" ? Math.max(window?.innerWidth || 0) : 0;
const breakpoints = Object.keys(Breakpoints);
const breakpoint = breakpoints.find((key, i) => {
if (i === breakpoints.length - 1) return vw >= Breakpoints[key];
return vw >= Breakpoints[key] && vw < Breakpoints[breakpoints[i + 1]];
});
if (!breakpoint) return 0;
const padding = ContainerPadding[breakpoint];
const result = breakpoint === "3xl"
? Math.min(((vw - padding * 2) / 14) * 12 - 20, ((1920 - padding * 2) / 14) * 12 - 20)
: ((vw - padding * 2) / 14) * 12 - 20;
setCenterColumn(result);
};
window.addEventListener("resize", updateCenterColumn);
updateCenterColumn();
return () => window.removeEventListener("resize", updateCenterColumn);
}, []);
return centerColumn;
};
const ImageSlider: FC<any> = ({ items, meta }) => {
const sliderRef = useRef<HTMLDivElement | null>(null);
const mutate = useSliderMutate();
const centerColumn = useCenterColumn();
useEffect(() => {
const ref = sliderRef.current;
const handleScroll = () => {
const max = (ref?.scrollWidth || 0) - (ref?.offsetWidth || 0);
const current = ref?.scrollLeft || 0;
const position = (current / max) * 100 || 0;
mutate?.setScrollPosition(meta.key, position);
};
handleScroll();
window.addEventListener("resize", handleScroll, true);
ref?.addEventListener("scroll", handleScroll, true);
return () => {
window.removeEventListener("resize", handleScroll);
ref?.removeEventListener("scroll", handleScroll);
};
}, [sliderRef, mutate, meta.key, centerColumn]);
return (
<BlockWrapper layout="full" className="ImageSlider">
<div className="ImageSlider__container w-full max-w-full mx-auto overflow-auto _scroll-hide relative">
<div
key={`Slider-Track--${meta.key}`}
ref={sliderRef}
onScroll={() => console.log('SCROLLL')}
className="ImageSlider__track w-fit flex pl-7 md:pl-[calc((100vw-(28px*2))/14+28px)] lg:pl-[calc((100vw-(38px*2))/14+38px)] xl:pl-[calc((100vw-(60px*2))/14+60px)] 2xl:pl-[calc((100vw-(76px*2))/14+76px)] 3xl:pl-[calc(max(((100vw-(96px*2))/14)+96px,(100vw-(1728px/14*12))/2))] relative overflow-auto _scroll-hide"
>
{items.map((item) => {
return (
<Link
key={item._key}
href={item.url || ""}
className={cx(
"relative flex-shrink-0 block mr-5 lg:mr-[26px] xl:mr-8 2xl:mr-10 3xl:mr-[52px] md:last:mr-[calc((100vw-(28px*2))/14+28px)] lg:last:mr-[calc((100vw-(38px*2))/14+38px)] xl:last:mr-[calc((100vw-(60px*2))/14+60px)] 2xl:last:mr-[calc((100vw-(76px*2))/14+76px)] 3xl:last:mr-[calc(max(((100vw-(96px*2))/14)+96px,(100vw-(1728px/14*12))/2))]",
{},
)}
style={{
width: (centerColumn / 6) * 5 - 20,
}}
>
<Image src="" alt="" />
</Link>
);
})}
</div>
</div>
</BlockWrapper>
);
};
export default ImageSlider;
If I remove the use of useCenterColumn
everything works as expected although the item
elements are sized incorrectly.
版权声明:本文标题:reactjs - useRef scroll event stops firing on parent after useEffect resizes ref's children - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741634985a2389589.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论