这是我对 hooks 方法的另一种看法,用于滚动显示和隐藏随机页面元素。
我的灵感来自:Dan Abramov's post here。
您可以在CodeSandbox demo 中查看完整的工作示例。
下面是useScroll自定义钩子的代码:
import React, { useState, useEffect } from "react";
export const useScroll = callback => {
const [scrollDirection, setScrollDirection] = useState(true);
const handleScroll = () => {
const direction = (() => {
// if scroll is at top or at bottom return null,
// so that it would be possible to catch and enforce a special behaviour in such a case.
if (
window.pageYOffset === 0 ||
window.innerHeight + Math.ceil(window.pageYOffset) >=
document.body.offsetHeight
)
return null;
// otherwise return the direction of the scroll
return scrollDirection < window.pageYOffset ? "down" : "up";
})();
callback(direction);
setScrollDirection(window.pageYOffset);
};
// adding and cleanning up de event listener
useEffect(() => {
window.addEventListener("scroll", handleScroll);
return () => window.removeEventListener("scroll", handleScroll);
});
};
这个钩子会像这样被消耗:
useScroll(direction => {
setScrollDirection(direction);
});
使用此自定义挂钩的完整组件:
import React, { useState } from "react";
import ReactDOM from "react-dom";
import CustomElement, { useScroll } from "./element";
import Scrollable from "./scrollable";
function Page() {
const [scrollDirection, setScrollDirection] = useState(null);
useScroll(direction => {
setScrollDirection(direction);
});
return (
<div>
{/* a custom element that implements some scroll direction behaviour */}
{/* "./element" exports useScroll hook and <CustomElement> */}
<CustomElement scrollDirection={scrollDirection} />
{/* just a lorem ipsum long text */}
<Scrollable />
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<Page />, rootElement);
最后是 CustomElement 的代码:
import React, { useState, useEffect } from "react";
export default props => {
const [elementVisible, setElementVisible] = useState(true);
const { scrollDirection } = props;
// when scroll direction changes element visibility adapts, but can do anything we want it to do
// U can use ScrollDirection and implement some page shake effect while scrolling
useEffect(() => {
setElementVisible(
scrollDirection === "down"
? false
: scrollDirection === "up"
? true
: true
);
}, [scrollDirection]);
return (
<div
style={{
background: "#ff0",
padding: "20px",
position: "fixed",
width: "100%",
display: `${elementVisible ? "inherit" : "none"}`
}}
>
element
</div>
);
};