![](/img/trans.png)
[英]Why call removeEventListener inside addEventListener callback?
[英]Why does addEventListener and removeEventListener inside useEffect() require an arrow function?
如果用户滚动到顶部,我正在尝试将 onTop state 设置为 true ,否则设置为 false 。 我尝试了以下。
function Test()
{
const [ onTop, setOnTop ] = useState( true )
const watchScroll = () =>
{
if ( window.scrollY < 100 ) setOnTop( true )
else setOnTop( false )
}
useEffect(() => {
window.addEventListener(`scroll`, watchScroll )
return window.removeEventListener(`scroll`, watchScroll )
}, [ watchScroll ])
return (
<div>{ onTop ? `On Top` : `Not On top` }</div>
)
}
上面的示例不起作用,但也不会引发错误。
function Test()
{
const [ onTop, setOnTop ] = useState( true )
const watchScroll = () =>
{
if ( window.scrollY < 100 ) setOnTop( true )
else setOnTop( false )
}
useEffect(() => {
window.addEventListener(`scroll`, () => watchScroll() )
return window.removeEventListener(`scroll`, () => watchScroll() )
}, [ watchScroll ])
return (
<div>{ onTop ? `On Top` : `Not On top` }</div>
)
}
请注意,我在第二个参数 function 中添加了箭头和大括号。 上面的示例按预期工作。 谁能解释为什么? 非常感谢!
如果你想清理你的效果,你需要返回一个 function。
useEffect(() => {
window.addEventListener(`scroll`, watchScroll )
return () => window.removeEventListener(`scroll`, watchScroll )
}, [ watchScroll ])
您最初的 function 无法正常工作的原因是,在每次重新渲染时,都会创建一个 function 的新实例,并且由于您将 ZC1C425268E67385D1AB5074F14C 的依赖项传递给使用,因此删除了前一个实例。 此外,由于您没有在清理 function 中执行window.removeEventListener
,因此它会立即运行,从而导致侦听器立即被删除。
您可以通过以下方式解决它
function Test()
{
const [ onTop, setOnTop ] = useState( true )
const watchScroll = useCallback(() =>
{
if ( window.scrollY < 100 ) setOnTop( true )
else setOnTop( false )
}, []);
useEffect(() => {
window.addEventListener(`scroll`, watchScroll )
return () => window.removeEventListener(`scroll`, watchScroll )
}, [ watchScroll ])
return (
<div>{ onTop ? `On Top` : `Not On top` }</div>
)
}
或者
function Test()
{
const [ onTop, setOnTop ] = useState( true )
useEffect(() => {
const watchScroll = () => {
if ( window.scrollY < 100 ) setOnTop( true )
else setOnTop( false )
}
window.addEventListener(`scroll`, watchScroll )
return ()=> window.removeEventListener(`scroll`, watchScroll )
}, [ ])
return (
<div>{ onTop ? `On Top` : `Not On top` }</div>
)
}
另请注意,使用箭头函数,您的解决方案有效,因为要删除EventListener,您需要传递相同的removeEventListener
参考才能使其正常工作,如果您使用箭头 function,则侦听器不会清理,因此您的实现工作
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.