React中重复if判断与DOM选择器代码的优化方案咨询
React中重复if判断与DOM选择器代码的优化方案咨询
嘿,这段代码的重复问题一眼就能看出来,咱们完全可以通过抽象重复逻辑的方式来简化它,不仅能让代码更清爽,以后再加类似的滚动触发效果也会方便很多!
先说说原代码的问题
你现在的代码里,每个区块(Prices/Contact/Moreinfo)都在做几乎一模一样的操作:重复调用document.querySelector查询DOM、重复写相同的条件判断、重复执行样式和类名的操作。这样不仅冗余,以后要修改判断条件或者样式时,得改好几处,很容易出错。
优化后的代码方案
咱们可以用React的useRef缓存DOM元素,再把重复逻辑抽成循环处理的方式,同时还能修复原代码里没清理滚动监听的内存泄漏问题:
import { useEffect, useRef } from 'react'; function YourComponent() { // 用useRef缓存所有需要操作的DOM元素,避免重复查询 const pricesSectionRef = useRef(null); const pricesArrRef = useRef(null); const contactSectionRef = useRef(null); const contactRef = useRef(null); const moreinfoSectionRef = useRef(null); const moreinfoRef = useRef(null); useEffect(() => { // 把每个区块的配置统一放到数组里,方便管理和扩展 const scrollTriggerConfigs = [ { sectionRef: pricesSectionRef, targetElementRef: pricesArrRef, animationClass: 'pricesArrAnim' }, { sectionRef: contactSectionRef, targetElementRef: contactRef, animationClass: 'contactAnim' }, { sectionRef: moreinfoSectionRef, targetElementRef: moreinfoRef, animationClass: 'moreinfoAnim' } ]; // 抽象滚动处理的核心逻辑 const handleScroll = () => { scrollTriggerConfigs.forEach(config => { // 先判断元素是否存在,避免组件未挂载时出现null报错 if (!config.sectionRef.current || !config.targetElementRef.current) return; const sectionTop = config.sectionRef.current.getBoundingClientRect().top; const targetElement = config.targetElementRef.current; if (sectionTop === 78) { targetElement.style.opacity = '1'; targetElement.classList.add(config.animationClass); } else if (sectionTop > 660) { targetElement.style.opacity = '0'; targetElement.classList.remove(config.animationClass); } }); }; // 添加滚动监听 document.addEventListener('scroll', handleScroll); // 清理函数:组件卸载时移除监听,防止内存泄漏 return () => { document.removeEventListener('scroll', handleScroll); }; }, []); // 空依赖数组,确保监听只挂载一次 return ( <div> {/* 给对应的元素绑定ref */} <div id="prices" ref={pricesSectionRef}>...</div> <div className="pricesArr" ref={pricesArrRef}>...</div> <div id="contact" ref={contactSectionRef}>...</div> <div className="contact" ref={contactRef}>...</div> <div id="moreinfo" ref={moreinfoSectionRef}>...</div> <div className="moreinfo" ref={moreinfoRef}>...</div> </div> ); }
额外的优化小建议
如果想让样式和代码彻底分离,你可以把opacity的控制也改成CSS类的方式:
/* 定义通用的可见性类 */ .section-visible { opacity: 1; } /* 保留你的动画类 */ .pricesArrAnim { /* 你的动画样式 */ }
然后把代码里的样式操作改成类名操作:
if (sectionTop === 78) { targetElement.classList.add('section-visible', config.animationClass); } else if (sectionTop > 660) { targetElement.classList.remove('section-visible', config.animationClass); }
这样就不用直接操作DOM样式了,更符合React的最佳实践,也方便后续修改样式。
备注:内容来源于stack exchange,提问作者Jesús Fernández
相关产品推荐
相关产品推荐

