Javascript 如何在自定义React钩子中编写条件逻辑
我正在创建一个自定义的React钩子。滚动目标元素可以是Javascript 如何在自定义React钩子中编写条件逻辑,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,我正在创建一个自定义的React钩子。滚动目标元素可以是myref.current或窗口对象 如果是myref.current目标值,我想使用scrollTop方法,如果是窗口对象,我想使用pageYOffset方法(因为scrollTop方法不适用于窗口) 如何创建此函数并以干净的方式编写 const useMyHook = (target: 'ref' | 'window') => { const [fade, setFade] = useState(false); const
myref.current
或窗口
对象
如果是myref.current
目标值,我想使用scrollTop
方法,如果是窗口
对象,我想使用pageYOffset
方法(因为scrollTop
方法不适用于窗口
)
如何创建此函数并以干净的方式编写
const useMyHook = (target: 'ref' | 'window') => {
const [fade, setFade] = useState(false);
const myRef = useRef<HTMLDivElement>(null);
// useEffect(() => {
// const onScroll = () => {
// if (window.pageYOffset > 50) {
// setFade(true);
// } else {
// setFade(false);
// }
// };
// window.addEventListener('scroll', onScroll);
// return () => window.removeEventListener('scroll', onScroll);
// }, []);
useEffect(() => {
const node = target === 'ref' ? scrollRef.current : window;
const onScroll = () => {
if (node) {
if (node.scrollTop > 50) {
setFade(true);
} else {
setFade(false);
}
}
};
if (node) {
node.addEventListener('scroll', onScroll);
}
return () => node?.removeEventListener('scroll', onScroll);
}, []);
return { myRef, fade };
};
export default useMyHook;
const useMyHook=(目标:“ref”|“window”)=>{
const[fade,setFade]=使用状态(false);
const myRef=useRef(null);
//useffect(()=>{
//const onScroll=()=>{
//如果(window.pageYOffset>50){
//setFade(真);
//}其他{
//setFade(假);
// }
// };
//window.addEventListener('scroll',onScroll);
//return()=>window.removeEventListener('scroll',onScroll);
// }, []);
useffect(()=>{
const node=target=='ref'?scrollRef.current:窗口;
const onScroll=()=>{
如果(节点){
如果(node.scrollTop>50){
setFade(真);
}否则{
setFade(假);
}
}
};
如果(节点){
node.addEventListener('scroll',onScroll);
}
return()=>node?.removeEventListener('scroll',onScroll);
}, []);
返回{myRef,fade};
};
导出默认useMyHook;
我本可以这样实现:
// node - any element you want to add event listener to, For eg: scrollRef.current or the window object
const useMyHook = (node) => {
const [fade, setFade] = useState(false);
useEffect(() => {
if (!node) return
const onScroll = () => {
const verticalScroll = node === window ? node.pageYOffset : node.scrollTop;
if (verticalScroll > 50) {
setFade(true);
} else {
setFade(false);
}
};
node.addEventListener('scroll', onScroll);
return () => node.removeEventListener('scroll', onScroll);
}, [node]);
return fade;
};
export default useMyHook;
PS:不确定您为什么使用myRef我认为这是最干净的(也删除了myRef,因为它不在使用中):
谢谢,在一个组件中,我必须使用
窗口
对象作为滚动目标,在另一个组件中,我必须使用ref(ReactuseRef
),这与我在material ui对话框中遇到的一些问题有关。在您的示例中,它仅基于ref,因为窗口
无权访问滚动条
method@meez添加了窗口或ref的区别谢谢,在一个组件中我必须使用窗口
对象作为滚动目标,在另一个组件中使用ref(ReactuseRef
),关于我在材质ui对话框中遇到的一些问题。在您的示例中,它仅基于ref,因为窗口
无法访问滚动顶
方法谢谢上面的任何想法?更新了答案
const useMyHook = node => {
const [fade, setFade] = useState(false);
useEffect(() => {
if (node){
const verticalScroll = node === window ? node.pageYOffset : node.scrollTop;
const onScroll = () => setFade(verticalScroll > 50);
node.addEventListener('scroll', onScroll);
}
return () => node?.removeEventListener('scroll', onScroll);
}, [node]);
return fade;
};
export default useMyHook;