英文:
Scrollable check in useEffect does not work on page refresh
问题
以下是您要翻译的代码部分:
const [isScrollableLeft, setIsScrollableLeft] = useState(false);
const [isScrollableRight, setIsScrollableRight] = useState(false);
const listRef = useRef();
useEffect(() => {
const checkScrollable = () => {
if (listRef.current) {
const { scrollLeft, scrollWidth, clientWidth } = listRef.current;
setIsScrollableLeft(scrollLeft > 0);
setIsScrollableRight(scrollWidth > clientWidth + scrollLeft);
}
};
if (listRef.current) {
listRef.current.addEventListener("scroll", checkScrollable);
// Initial check
checkScrollable();
}
// Clean up the event listener when the component is unmounted
return () => {
if (listRef.current) {
listRef.current.removeEventListener("scroll", checkScrollable);
}
};
}, []);
<div className="community-overall-link-container">
{isScrollableLeft && <div className="link-container-arrow arrow-left-main" onClick={scrollToStart}><img src={leftDirection} alt="←" /></div>}
<ul ref={listRef} className="community-links-container">
<li className={`community-links-item ${communityLink === 1 ? 'community-links-item-active' : ''}`} onClick={() => setCommunityLink(1)}>Upcoming Hangout</li>
<li className={`community-links-item ${communityLink === 2 ? 'community-links-item-active' : ''}`} onClick={() => setCommunityLink(2)}>Discussions</li>
<li className={`community-links-item ${communityLink === 3 ? 'community-links-item-active' : ''}`} onClick={() => setCommunityLink(3)}>Organizers</li>
</ul>
{isScrollableRight && <div className="link-container-arrow arrow-right-main" onClick={scrollToEnd}><img src={rightDirection} alt="→" /></div>}
</div>
英文:
I have a React component where I'm displaying a list of items. The list can be scrollable depending on the number of items. I want to display left and right arrow buttons only if the list is scrollable in those directions.
To achieve this, I'm using a useEffect hook that checks if the list is scrollable and sets state variables accordingly. It works, however, when I refresh the page it no longer works, the arrows don't appear even when the list is scrollable. Here's my code:
const [isScrollableLeft, setIsScrollableLeft] = useState(false);
const [isScrollableRight, setIsScrollableRight] = useState(false);
const listRef = useRef();
useEffect(() => {
const checkScrollable = () => {
if (listRef.current) {
const { scrollLeft, scrollWidth, clientWidth } = listRef.current;
setIsScrollableLeft(scrollLeft > 0);
setIsScrollableRight(scrollWidth > clientWidth + scrollLeft);
}
};
if (listRef.current) {
listRef.current.addEventListener("scroll", checkScrollable);
// Initial check
checkScrollable();
}
// Clean up the event listener when the component is unmounted
return () => {
if (listRef.current) {
listRef.current.removeEventListener("scroll", checkScrollable);
}
};
}, []);
And here's the JSX:
<div className="community-overall-link-container">
{isScrollableLeft && <div className="link-container-arrow arrow-left-main" onClick={scrollToStart}><img src={leftDirection} alt="←" /></div>}
<ul ref={listRef} className="community-links-container">
<li className={`community-links-item ${communityLink === 1 ? 'community-links-item-active' : ''}`} onClick={() => setCommunityLink(1)}>Upcoming Hangout</li>
<li className={`community-links-item ${communityLink === 2 ? 'community-links-item-active' : ''}`} onClick={() => setCommunityLink(2)}>Discussions</li>
<li className={`community-links-item ${communityLink === 3 ? 'community-links-item-active' : ''}`} onClick={() => setCommunityLink(3)}>Organizers</li>
</ul>
{isScrollableRight && <div className="link-container-arrow arrow-right-main" onClick={scrollToEnd}><img src={rightDirection} alt="→" /></div>}
</div>
答案1
得分: 2
你可以将checkScrollable
函数封装在一个单独的函数内,并在组件挂载时通过将函数调用添加到useEffect
的依赖数组中来调用它。
如果不使用依赖数组,在页面刷新时,组件可能尚未挂载,初始的useEffect
不会被调用。这可能是为什么状态变量isScrollableLeft
和isScrollableRight
没有被设置的原因。
const [isScrollableLeft, setIsScrollableLeft] = useState(false);
const [isScrollableRight, setIsScrollableRight] = useState(false);
const listRef = useRef();
const checkScrollable = () => {
if (listRef.current) {
const { scrollLeft, scrollWidth, clientWidth } = listRef.current;
setIsScrollableLeft(scrollLeft > 0);
setIsScrollableRight(scrollWidth > clientWidth + scrollLeft);
}
};
useEffect(() => {
// 在初始挂载时运行
checkScrollable();
if (listRef.current) {
listRef.current.addEventListener("scroll", checkScrollable);
}
// 在卸载时清除事件监听器
return () => {
if (listRef.current) {
listRef.current.removeEventListener("scroll", checkScrollable);
}
};
}, [checkScrollable]); // 在挂载时再次调用函数
英文:
You could wrap the checkScrollable
function inside a separate function and call it when the component is mounted by adding the function call inside the useEffect dependency array.
Without using the dependency array, when page refreshes the component may not have mounted yet and the initial useEffect doesn't get called. This could be why the state variables isScrollableLeft
and isScrollableRight
are not getting set.
const [isScrollableLeft, setIsScrollableLeft] = useState(false);
const [isScrollableRight, setIsScrollableRight] = useState(false);
const listRef = useRef();
const checkScrollable = () => {
if (listRef.current) {
const { scrollLeft, scrollWidth, clientWidth } = listRef.current;
setIsScrollableLeft(scrollLeft > 0);
setIsScrollableRight(scrollWidth > clientWidth + scrollLeft);
}
};
useEffect(() => {
// Run on initial mount
checkScrollable();
if (listRef.current) {
listRef.current.addEventListener("scroll", checkScrollable);
}
// Clean up the event listener when unmounted
return () => {
if (listRef.current) {
listRef.current.removeEventListener("scroll", checkScrollable);
}
};
}, [checkScrollable]); // Call the function again on mount
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论