这里:
const useHideOnScroll = () => {
const prevScrollY = React.useRef<number>();
const [isHidden, setIsHidden] = React.useState(false);
React.useEffect(() => {
const onScroll = () => {
setIsHidden(isHidden => {
const scrolledDown = window.scrollY > prevScrollY.current!;
if (scrolledDown && !isHidden) {
return true;
} else if (!scrolledDown && isHidden) {
return false;
} else {
prevScrollY.current = window.scrollY;
return isHidden;
}
});
};
console.log("adding listener");
window.addEventListener("scroll", onScroll);
return () => {
window.removeEventListener("scroll", onScroll);
};
}, []);
return isHidden;
};
const Navbar = () => {
const isHidden = useHideOnScroll();
console.info("rerender");
return isHidden ? null : <div className="navbar">navbar</div>;
};
export default Navbar;
您可能会担心会setIsHidden
导致在 each 上onScroll
重新渲染,因为它总是返回一些新的状态值,但是 setter fromuseState
足够聪明,只有在值实际更改时才更新。
此外,您的.navbar
(我已向其中添加了一个类)不应在布局出现时更改布局,否则您的代码段将被锁定在无限循环中。这里也有合适的样式:
.navbar {
position: fixed;
top: 0;
left: 0;
right: 0;
height: 30px;
background: rgba(255, 255, 255, 0.8);
}
完整的 CodeSandbox:https ://codesandbox.io/s/13kr4xqrwq