React中如何从Footer组件滚动到Services页面指定Div
React 点击链接滚动到指定元素的解决方案
哈希方法失效的常见原因
- React 单页应用路由切换时,浏览器默认不会触发哈希锚点的滚动行为
- 目标元素的
id拼写错误,或元素未完成渲染就执行了滚动操作 - 页面存在自定义滚动容器(如设置了
overflow: auto的父元素),滚动上下文不是window
方案一:使用 useRef + scrollIntoView(组件间通信场景)
如果 Footer 和 Services 属于不同组件层级,可通过以下方式直接控制目标元素滚动:
- 在 Services 组件中给目标元素绑定 ref
import { useRef } from 'react'; const Services = () => { const servicesMsgRef = useRef(null); return ( <div className="services-page"> {/* 页面其他内容 */} <div ref={servicesMsgRef} id="OurServicesMessage"> 这里是服务介绍内容 </div> </div> ); }; export default Services;
- 在 Footer 组件中处理点击事件
无需复杂状态管理,可直接通过 DOM API 获取元素并触发滚动:
const Footer = () => { const scrollToServices = () => { const targetElement = document.getElementById('OurServicesMessage'); if (targetElement) { targetElement.scrollIntoView({ behavior: 'smooth', // 开启平滑滚动 block: 'start' // 滚动到元素顶部对齐 }); } }; return ( <footer> <button onClick={scrollToServices} type="button"> 查看我们的服务 </button> {/* 或用a标签并阻止默认跳转 */} <a href="#" onClick={(e) => { e.preventDefault(); scrollToServices(); }}>查看我们的服务</a> </footer> ); };
方案二:适配路由场景(跨路由滚动)
如果点击 Footer 链接需要先跳转到 Services 页面再滚动,结合 react-router-dom 处理:
- 在路由根组件中监听路由变化
import { useEffect } from 'react'; import { useLocation } from 'react-router-dom'; const App = () => { const location = useLocation(); useEffect(() => { // 路由切换完成后检查哈希值并滚动 if (location.hash) { const targetId = location.hash.slice(1); // 去除哈希前缀# const targetElement = document.getElementById(targetId); if (targetElement) { // 延迟执行确保元素已渲染完成 setTimeout(() => { targetElement.scrollIntoView({ behavior: 'smooth' }); }, 100); } } }, [location]); return ( <Routes> <Route path="/services" element={<Services />} /> {/* 其他路由配置 */} </Routes> <Footer /> ); };
- Footer 中使用
Link组件跳转
import { Link } from 'react-router-dom'; const Footer = () => { return ( <footer> <Link to="/services#OurServicesMessage">查看我们的服务</Link> </footer> ); };
额外注意事项
- 确保目标元素的
id在页面中唯一,避免冲突 - 如果滚动容器是某个父级元素(而非
window),需获取该容器的 ref,调用containerRef.current.scrollTop = targetElement.offsetTop - 容器偏移量实现精准滚动 - 平滑滚动的
behavior: 'smooth'需现代浏览器支持,如需兼容低版本可添加对应 polyfill
内容的提问来源于stack exchange,提问作者K.Z
相关产品推荐
相关产品推荐

