如何使用document.querySelector选择CSS Module生成的类名?
报错根因
你代码中的错误本质是两个问题叠加导致的:
document.querySelector()需要传入符合CSS选择器规范的字符串,styles.scrollValue返回的是编译后的纯类名字符串(例如scrollValue_6fa2x),没有前缀.,此时方法会把它当成标签名查找,自然返回null- 你的
useEffect没有传入空依赖数组,会在每次组件渲染时重复注册/销毁滚动事件,极端情况下会出现组件还没完成DOM挂载就触发事件回调的情况
解决方案1:React官方推荐实践(优先选择,完全不破坏CSS Modules隔离)
直接使用useRef绑定目标元素,无需任何DOM查询操作:
import { useEffect, useRef } from "react"; import styles from "./Navbar.module.scss"; const Navbar = () => { // 声明ref绑定目标元素 const scrollValueRef = useRef(null); const handleScroll = () => { // 直接通过ref访问元素,无需查询 if (scrollValueRef.current) { scrollValueRef.current.innerHTML = scrollY; } }; useEffect(() => { document.addEventListener("scroll", handleScroll); return () => { document.removeEventListener("scroll", handleScroll); }; // 加空依赖数组,只在组件挂载/卸载时执行一次 }, []); return ( <nav className={styles.navbar}> <div className={styles.content}> {/* 把ref绑定到目标元素上 */} <h1 ref={scrollValueRef} className={styles.scrollValue}>0</h1> </div> </nav> ); };
解决方案2:坚持使用querySelector的实现(无需额外加全局类名)
只需要给类名拼接.前缀,同时补全空依赖和元素存在性判断即可:
import { useEffect } from "react"; import styles from "./Navbar.module.scss"; const Navbar = () => { const handleScroll = () => { // 拼接.前缀,符合类选择器规范 const el = document.querySelector(`.${styles.scrollValue}`); if (el) { el.innerHTML = scrollY; } }; useEffect(() => { document.addEventListener("scroll", handleScroll); return () => { document.removeEventListener("scroll", handleScroll); }; }, []); return ( <nav className={styles.navbar}> <div className={styles.content}> <h1 className={styles.scrollValue}>0</h1> </div> </nav> ); };
内容的提问来源于stack exchange,提问作者Anthony Dinino
相关产品推荐
相关产品推荐

