[英]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.