我正在尝试做的事情我正在使用React JS构建一个Netflix克隆。我已经创建了一个视频组件列表来水平列出视频项。我已经将容器的overflow-x设置为隐藏,这样我就可以使用左按钮和右按钮来左右滚动。通过isOverflowLeft和isOverflowRight的布尔值,我想让按钮显示:当没有溢出时为none。我使用useRef()使这个函数工作。当单击左键或右键时,scrollLeft更新为+- 400。
问题问题是当组件呈现时,scrollWidth显示了一个不同的数字。在我的例子中,scrollWidth应该是4000,但它显示的宽度与clientWidth相同。你能检查我的代码并告诉我我哪里做错了吗?
const VideoList = memo(({ label, fetchUrl, isLarge }) => {
const listRef = useRef();
const [isOverflowLeft, setIsOverflowLeft] = useState(false);
const [isOverflowRight, setIsOverflowRight] = useState(false);
const [scrollLeft, setScrollLeft] = useState(0);
const handleScrollRight = () => {
if (isOverflowRight) {
listRef.current.scrollLeft += 400;
setScrollLeft((prev) => prev + 400);
}
};
const handleScrollLeft = () => {
if (isOverflowLeft) {
listRef.current.scrollLeft -= 400;
setScrollLeft((prev) => prev - 400);
}
};
useEffect(() => {
async function fetchData() {
const requestOptions = {
method: 'GET',
redirect: 'follow',
};
await fetch(fetchUrl, requestOptions)
.then((response) => response.json())
.then((data) => setMovies(data.results))
.catch((error) => console.log('error', error));
}
fetchData();
}, [fetchUrl]);
useEffect(() => {
setIsOverflowLeft(scrollLeft > 0);
setIsOverflowRight(
scrollLeft + listRef.current.clientWidth < listRef.current.scrollWidth
);
console.log(
`clientWidth: ${listRef.current.clientWidth} scrollWidth: ${listRef.current.scrollWidth} scrollLeft: ${scrollLeft} isOverflowLeft: ${isOverflowLeft} isOverflowRight: ${isOverflowRight}`
);
}, [scrollLeft, isOverflowLeft, isOverflowRight]);
return (
<section className={styles.container}>
<h1 className={styles.title}>{label}</h1>
<div className={styles.list} ref={listRef}>
<button
className={isOverflowLeft ? styles.scrollLeft : styles.hidden}
onClick={handleScrollLeft}
>
<BsChevronCompactLeft className={styles.scrollIcon} />
</button>
{movies.map((movie) => {
return <VideoItem key={movie.id} video={movie} isLarge={isLarge} />;
})}
<button
className={isOverflowRight ? styles.scrollRight : styles.hidden}
onClick={handleScrollRight}
>
<BsChevronCompactRight className={styles.scrollIcon} />
</button>
</div>
</section>
);
});
export default memo(VideoList);
屏幕截图x1c 0d1x
3条答案
按热度按时间b4lqfgs41#
尝试将
listRef.current
添加到useEffect依赖项数组中,因为当列表元素溢出时,listRef.current
值会发生变化,然后它会给予您正确的.scrollWidth
值。因此,您的代码应该如下所示:92vpleto2#
我遇到了同样的问题,我找到了一个解决办法,我想通过计算滚动和更新滑块的宽度来设置滑块的约束。显然,问题是在页面呈现后。scrollWidth和.offsetWidth/.clientWidth返回相同的值。所以我在执行useEffect中的内容之前添加了一个小延迟,它起作用了。下面是我的代码:
goucqfw63#
这里也有同样的问题,但是我了解到可以使用
requestAnimationFrame
在useEffect
中获得正确和准确的scrollWidth
。