与共享的React自定义钩子和window.onscroll属性冲突

时间:2020-02-13 08:52:26

标签: reactjs window react-hooks

我有一个React自定义钩子,它根据window.pageYOffset值显示/隐藏一个按钮:

const useHandlerOnScroll = height => {

    const [buttonVisible, showUpButton] = useState(false);
    useEffect ( () => {
        window.onscroll = () => {
            window.pageYOffset >= height ? showUpButton(true) : showUpButton(false)
        }
    })  

    return { buttonVisible }
}

每当我需要使用它时,我只需在组件中解构钩子并获取buttonVisible值:

export default () => {

    const { buttonVisible } = useHandlerOnScroll(450)

    const goTop = () => window.scrollTo({ top: 0, behavior: 'smooth' })

    return buttonVisible 
      ? <BottoneTop onClick={() => }> <FaChevronCircleUp /> </BottoneTop> 
        : null
}

只要我仅将其用于一个组件,此过程就有效,如果我导出useHandlerOnScroll钩子并在另一个按钮上使用它,则只会显示一个按钮。

我不明白为什么,因为我认为导入钩子的每个组件都会创建该钩子的新实例。

我也尝试了useReducer,但是结果是相同的:我不能将钩子与多个组件一起使用。

PS:我的猜测是window.oncroll属性在这样调用时会引起一些冲突(由于性能原因,我仍然不希望使用addEventListener。)

1 个答案:

答案 0 :(得分:0)

刚刚发现.onscroll方法一次只能分配给一个对象,所以这就是冲突的根源:

一次只能将一个onscroll处理程序分配给一个对象。为了获得更大的灵活性,您可以将滚动事件传递给EventTarget.addEventListener()方法。

来自:MDN Web docs - GlobalEventHandlers.onscroll

我解决了window.addEventListener("scroll", callbackFunction )的问题。