Javascript 使用useCallback/UseMoom冻结关闭

Javascript 使用useCallback/UseMoom冻结关闭,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,我看到了一些奇怪的行为,useCallback函数似乎无法访问外部作用域 这里描述了这一点: 虽然可以通过将所有内容添加到数组中来轻松地重新计算,但这似乎与直觉相反。所以我想知道最好的处理方法是什么 这是密码 import React,{useCallback,useState,useffect,useRef}来自“React”; 从“类名称”导入类名称; 从“../../hooks/use event listener”导入useEventListener; 从“tinybounce”进口ti

我看到了一些奇怪的行为,
useCallback
函数似乎无法访问外部作用域

这里描述了这一点:

虽然可以通过将所有内容添加到数组中来轻松地重新计算,但这似乎与直觉相反。所以我想知道最好的处理方法是什么

这是密码

import React,{useCallback,useState,useffect,useRef}来自“React”;
从“类名称”导入类名称;
从“../../hooks/use event listener”导入useEventListener;
从“tinybounce”进口tinybounce;
从“../../utils/Scroll”导入滚动;
导出默认函数DefaultMainPlayer({children,className}){
const[scrollThreshold,setScrollThreshold]=useState(0);
const[inView,setInView]=useState(true);
const[didUserClose,setDidUserClose]=useState(false);
const el=useRef();
常量scrollHandler=useCallback(()=>{
//scrollThreshold和inView将被“冻结”,除非它们位于下面的数组中
const isVisible=Scroll.getPosition()setScrollThreshold(Scroll.getElementCoordinates(el.current.bottom))300,
[]
);
//如果滚动阈值更新,让我们调用滚动处理程序
useEffect(scrollHandler,[scrollThreshold]);
//调用调整大小处理程序一次
useEffect(resizeHandler,[]);
//我希望滚动处理程序永远不要更改,因为它确实不需要更改
useEventListener('scroll',scrollHandler);
useEventListener('resize',resizeHandler);
返回(
{儿童}
);
}
下面是“使用事件侦听器”的代码``

从'react'导入{useRef,useffect};
导出默认函数useEventListener(事件名称、处理程序、元素=窗口){
const savedHandler=useRef();
useffect(()=>{
savedHandler.current=处理程序;
},[handler]);
useffect(()=>{
const issuported=element&&element.addEventListener;
如果(!isSupported)返回;
const eventListener=event=>savedHandler.current(事件);
//添加事件侦听器
元素addEventListener(eventName,eventListener);
//清除时删除事件侦听器
return()=>{
removeEventListener(eventName,eventListener);
};
},
[事件名称,元素]
);
};
由于函数不相等,我试图避免
scrollHandler
一直在更改。我尝试了
useMemo
(将函数作为值返回),但结果是相同的。不要更新
scrollThreshold

虽然这两个变量看起来“有点”,但很容易需要更多,而且感觉不对


有没有办法解决这个问题或以不同的方式处理它?

问题似乎是您在回调中使用了一个状态变量,然后在
useffect
中进行设置。可能没有简单的方法来处理这个问题,请参阅

两种选择


不要使用
useCallback
。这样在运行函数时,它将使用最新的
scrollThreshold
inView
。还将更改的变量作为
useEventListener
的依赖项传递给
useffect
(这需要一些重构):


useCallback
scrollThreshold一起使用,将inView
作为依赖项。 在
useventlistener
或任何使用它的钩子中,使用作为添加/删除事件处理程序中的依赖项传递的函数:

useEffect(() => {
    const isSupported = element && element.addEventListener;
    if (!isSupported) return;

    const eventListener = handler;

    // Add event listener
    element.addEventListener(eventName, eventListener);

    // Remove event listener on cleanup
    return () => {
        element.removeEventListener(eventName, eventListener);
    };
}, [eventName, element, handler]);

如果有不清楚的地方,请告诉我。

useEventListener如何处理接收到的函数?我已经添加了代码@Alvaro。据我所知,唯一的问题是scrollHandler没有使用正确的
scrollThreshold
?useEventListener似乎没有任何问题('scroll',scrollHandler);,对吗?是的,
useEventlistener
工作正常,对scroll和下面的
resize
调用也能正常工作。看来类对于这类组件来说就不那么麻烦了!(现在)谢谢!
useEffect(() => {
    const isSupported = element && element.addEventListener;
    if (!isSupported) return;

    const eventListener = handler;

    // Add event listener
    element.addEventListener(eventName, eventListener);

    // Remove event listener on cleanup
    return () => {
        element.removeEventListener(eventName, eventListener);
    };
}, [eventName, element, handler]);