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

使用react-router-dom v6.9的React SPA无法实现连续滚动,切换路由仅显示当前页

问题根源与解决方案

你的核心问题在于:你想要的是「单页面连续滚动」效果,但当前用的是react-router的「多路由切换」模式。react-router v6的Routes组件只会渲染当前匹配的路由元素,其他路由对应的组件会被卸载,所以点击导航后只会显示当前页面,其他页面自然消失——这是路由的正常行为,不是配置错误。

如果你要实现从第一页连续滚动到最后一页的效果,应该调整实现方案,而不是用多路由切换,以下是两种可行思路:


思路一:改为单页面锚点导航(推荐)

把所有页面组件放在同一个父容器里,通过锚点或滚动控制定位,完全不需要路由切换:

1. 修改App.js

去掉Routes和路由配置,把所有页面组件依次渲染:

function App() {
  return (
    <div>
      <Navigation />
      <div id="home">
        <Home />
      </div>
      <div id="aboutus">
        <AboutUs />
      </div>
      <div id="services">
        <Services />
      </div>
      <div id="offers">
        <Offers />
      </div>
      <div id="contact">
        <ContactUs />
      </div>
      <Footer />
    </div>
  );
}

2. 修改导航组件

把Link换成原生<a>标签(或者用React的滚动API实现平滑滚动):

<Nav className="justify-content-evenly align-items-center flex-grow-1 nav-tab">
  <a href="#home">Home</a>
  <a href="#aboutus">About Us</a>
  <a href="#services">Services</a>
  <a href="#offers">Packages</a>
  <a href="#contact">Contact Us</a>
</Nav>

如果需要平滑滚动效果,给页面添加CSS:

html {
  scroll-behavior: smooth;
}

思路二:保留路由但实现滚动联动(不推荐)

如果你一定要保留路由结构,同时实现滚动效果,可以通过监听路由变化,手动滚动到对应页面位置,但这种方式不符合SPA路由的设计初衷,且会保留所有组件渲染,可能带来性能问题:

1. 修改App.js,渲染所有页面组件并监听路由滚动

import { useLocation } from 'react-router-dom';
import { useEffect } from 'react';

function App() {
  const location = useLocation();

  useEffect(() => {
    const targetId = location.pathname === '/' ? 'home' : location.pathname.slice(1);
    const element = document.getElementById(targetId);
    if (element) {
      element.scrollIntoView({ behavior: 'smooth' });
    }
  }, [location]);

  return (
    <Router>
      <Navigation />
      <div>
        <div id="home">
          <Home />
        </div>
        <div id="aboutus">
          <AboutUs />
        </div>
        <div id="services">
          <Services />
        </div>
        <div id="offers">
          <Offers />
        </div>
        <div id="contact">
          <ContactUs />
        </div>
      </div>
      <Footer />
    </Router>
  );
}

2. 隐藏未激活页面(可选)

如果不想同时显示所有页面,可以通过路由判断控制显示:

// 在页面组件中添加判断
function Home() {
  const location = useLocation();
  const isActive = location.pathname === '/';
  return (
    <div className={`page-section ${isActive ? '' : 'hidden'}`}>
      {/* 页面内容 */}
    </div>
  );
}

// 对应的CSS
.page-section.hidden {
  display: none;
}

但这种方式本质上绕开了路由的核心功能,不如思路一直接高效。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 06:43:12