React中使用useRef与window滚动事件时出现undefined报错问题
解决Sticky导航栏滚动时的undefined报错问题
问题原因
你遇到的undefined报错主要来自两个场景:
- 组件初始化阶段,
toolbarRef.current还未指向DOM元素时,scroll事件就已触发,此时访问toolbarRef.current.getBoundingClientRect()会直接报错。 - 直接给window绑定scroll监听后,组件卸载时未移除该监听,不仅会造成内存泄漏,还会在组件卸载后触发事件时,访问已不存在的ref导致报错。
修复方案
使用React的useEffect管理scroll事件的生命周期,确保监听仅在组件挂载后添加、卸载时移除;同时在事件处理逻辑里先判断ref是否有效,再执行后续操作。
修改后的代码
import { memo, useRef, useEffect } from 'react'; import styles from '../styles/NotesToolbar.module.css'; import FilterSelect from './FilterSelect'; import NotesCounter from './NotesCounter'; const NotesToolbar = () => { const toolbarRef = useRef(); useEffect(() => { const handleScroll = () => { // 先确认ref已关联DOM元素 if (!toolbarRef.current) return; const rect = toolbarRef.current.getBoundingClientRect(); if (rect.top <= 0) { toolbarRef.current.classList.add(styles.ToolbarSticky); } else { toolbarRef.current.classList.remove(styles.ToolbarSticky); } }; // 组件挂载后添加滚动监听 window.addEventListener('scroll', handleScroll); // 组件卸载时清除监听 return () => window.removeEventListener('scroll', handleScroll); }, []); // 空依赖数组确保监听只绑定一次 return ( <div className={styles.Toolbar} ref={toolbarRef}> <div className={styles.ToolbarLeft}> <FilterSelect /> </div> <div className={styles.ToolbarRight}> <NotesCounter /> </div> </div> ); }; export default memo(NotesToolbar);
关键说明
useEffect的空依赖数组保证监听仅在组件挂载时初始化一次,避免重复绑定;返回的清理函数会在组件卸载时自动移除监听。- 事件处理函数里先判断
toolbarRef.current是否存在,从根源避免undefined报错。 - 将
handleScroll定义在useEffect内部,确保它能正确捕获最新的ref引用,符合React Hooks的使用规范。
内容的提问来源于stack exchange,提问作者LexxCh
相关产品推荐
相关产品推荐

