Problem with transition height

Hi guys, I'm trying to hide the tabs on scroll down and show on scroll up but I'm facing this problem. Can anyone help me? I'm using MUI and this is how I toggle the height.
<Box
sx={{
display: "grid",
gridTemplateRows: isShowTabs ? "1fr" : "0fr",
transition: "500ms grid-template-rows ease",
}}
>
......
</Box>
<Box
sx={{
display: "grid",
gridTemplateRows: isShowTabs ? "1fr" : "0fr",
transition: "500ms grid-template-rows ease",
}}
>
......
</Box>
12 Replies
empty
empty2w ago
const [lastScrollTop, setLastScrollTop] = useState(0);
const [isShowTabs, setIsShowTabs] = useState(true);
useEffect(() => {
const scrollableDiv = document.querySelector("#scrollableDiv");
const handleOnscroll = () => {
if (!scrollableDiv) return;
const scrollPos = scrollableDiv?.scrollTop;

if (scrollPos > lastScrollTop) setIsShowTabs(false);
else setIsShowTabs(true);
setLastScrollTop(scrollPos);
};
scrollableDiv?.addEventListener("scroll", handleOnscroll);

return () => {
scrollableDiv?.removeEventListener("scroll", handleOnscroll);
};
}, [lastScrollTop]);
const [lastScrollTop, setLastScrollTop] = useState(0);
const [isShowTabs, setIsShowTabs] = useState(true);
useEffect(() => {
const scrollableDiv = document.querySelector("#scrollableDiv");
const handleOnscroll = () => {
if (!scrollableDiv) return;
const scrollPos = scrollableDiv?.scrollTop;

if (scrollPos > lastScrollTop) setIsShowTabs(false);
else setIsShowTabs(true);
setLastScrollTop(scrollPos);
};
scrollableDiv?.addEventListener("scroll", handleOnscroll);

return () => {
scrollableDiv?.removeEventListener("scroll", handleOnscroll);
};
}, [lastScrollTop]);
This is how I toggle the isShowTabs. I also tried to use sticky but it did not work. I dont know where I'm wrong
clevermissfox
clevermissfox2w ago
do you have overflow hidden on whatever lives in that row? the tabs parent?
empty
empty2w ago
I have overflow hidden on child of Box component
clevermissfox
clevermissfox2w ago
Have you looked in the dev tools at the styles to see if there’s a specificity issue or to confirm if all those styles are being applied ?
empty
empty2w ago
The style is applied. You can take a look at my video. Because the scrollPos changes nonstop so the isShowTabs changes consecutively and the style toggles as well
clevermissfox
clevermissfox2w ago
Can you put the relevant component /code into a codepen or a codesandbox.io. Snippets and screen recordings are hard to debug
empty
empty2w ago
Ok i'll do it https://codesandbox.io/p/sandbox/navbar-hide-on-scroll-down-76fh76?file=%2Fsrc%2FApp.js%3A142%2C1 The component structure is quite different but the bug still occurs. Can you please take a look
tototriou15
tototriou152w ago
use position: fixed and it works instead of position sticky your component is already on top of the page
tototriou15
tototriou152w ago
is that what you want ?
No description
clevermissfox
clevermissfox2w ago
i didnt see a position sticky in the css, is that being loaded in from a dependancy? I think the issue comes from this (although not a react master so just a hunch)
if (scrollPos > lastScrollTopRef.current) setIsShowTabs(false);
else setIsShowTabs(true);
lastScrollTopRef.current = scrollPos;
if (scrollPos > lastScrollTopRef.current) setIsShowTabs(false);
else setIsShowTabs(true);
lastScrollTopRef.current = scrollPos;
it seems to be flickering back and forth from isShowTabs between true and false because lastScrollTopRef starts at 0, which means scrollPos IS greater than it and isShowTabs is false. then lastScrollTopRef.current is set to scrollPos which is not greater than scrollPos (its equal to) so the 'else' is triggered which is IsShowTabs to true. im getting some conflicting information whether in Ract18 an empty dependancy array will trigger a rerender :
In React 18, an empty dependency array in useEffect no longer guarantees that the effect will only run once on mount. This is due to the introduction of the new Strict Mode behavior and concurrent rendering in React 18. When using an empty dependency array with useEffect in React 18, the effect may be called twice during the initial render - once during the render phase and again during the commit phase. This can lead to an infinite loop if the effect updates state, causing a re-render, which then triggers the effect again, and so on.
So between the renders and the toggling of isShowTabs between true or false and the transition time to toggle your grid rows, its causing a flicker. oh i see the pos sticky in the dev tools and i must be wrong, and @tototriou15 is correct because setting it to fixed seems to fix everythign
tototriou15
tototriou152w ago
sorry i changed it to fixed in my gif to make it work
clevermissfox
clevermissfox2w ago
yeah it fixes the flicker, well done!
Want results from more Discord servers?
Add your server
More Posts