You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React组件useEffect中removeEventListener失效问题求助

问题根源与修复方案

你的问题核心是添加的滚动监听函数和尝试移除的不是同一个引用,导致removeEventListener完全无效,具体问题点和修复步骤如下:

问题拆解

  1. 你在addEventListener里传入的是一个匿名箭头函数,但移除时传的是parallax函数——这俩是完全不同的函数引用,浏览器找不到要移除的监听,自然不会生效。
  2. parallax函数每次组件渲染都会重新创建,即使你用它作为监听,后续移除时的parallax已经是新的函数引用了,同样会失败。
  3. 监听用的是document,移除却用window,虽然浏览器环境下二者的scroll事件本质相通,但这种不一致可能引发隐性问题。

修复后的代码

import { useEffect, useCallback } from 'react';
import { useInView } from 'react-intersection-observer';

const GridTextParallax = () => {
    const { trigger, inView } = useInView({
        threshold: [0, 0.8],
    });
    
    // 用useCallback包裹,确保函数引用稳定
    const parallax = useCallback((scrolling) => {       
        if (scrolling > 0) {
            // 你的视差逻辑
        }
    }, []);

    // 抽成具名的滚动处理函数,确保引用唯一
    const handleScroll = useCallback(() => {
        const scrolling = // 计算滚动比例的逻辑
        parallax(scrolling);
    }, [parallax]);

    useEffect(() => {
        if (inView) {
            // 统一用window作为监听目标
            window.addEventListener('scroll', handleScroll);
            // 清理函数:组件卸载或inView变化时移除监听
            return () => {
                window.removeEventListener('scroll', handleScroll);
            };
        }
        // 当inView变为false时,useEffect会重新执行,此时不会添加监听,也不需要额外移除(因为上一次的清理函数已经执行了)
    }, [inView, handleScroll]);


    return (
        <section id="layer" ref={trigger} >
            {/* 前端内容 */}
        </section>
    )
}

export default GridTextParallax 

关键改动说明

  • 用useCallback包裹parallax和handleScroll,保证组件重渲染时函数引用不会改变,确保添加和移除的是同一个函数。
  • 将滚动处理逻辑抽成具名函数handleScroll,替代原来的匿名箭头函数,让addEventListener和removeEventListener使用完全相同的函数引用。
  • 统一使用window作为scroll事件的监听目标,避免环境差异导致的问题。
  • 简化useEffect的逻辑:当inView变为true时添加监听,清理函数负责移除;当inView变为false时,useEffect的依赖变化,会先执行上一次的清理函数移除监听,再执行新的effect(此时inView为false,不会添加新监听)。

内容的提问来源于stack exchange,提问作者Arthur Fortin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 10:17:47