Javascript 如何在自定义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

我正在创建一个自定义的React钩子。滚动目标元素可以是
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(React
useRef
),这与我在material ui对话框中遇到的一些问题有关。在您的示例中,它仅基于ref,因为
窗口
无权访问
滚动条
method@meez添加了窗口或ref的区别谢谢,在一个组件中我必须使用
窗口
对象作为滚动目标,在另一个组件中使用ref(React
useRef
),关于我在材质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;