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

如何在react-router-dom与react-redux项目中避免路由切换时组件重复渲染

React路由切换重复请求与卡顿优化方案

注意:你当前的代码存在命名冲突问题,侧边栏组件和首页组件都使用了Home作为函数名,会导致路由渲染异常,建议先将侧边栏组件重命名为Sidebar避免冲突。

一、避免重复发起请求的方案

方案1:请求前增加数据存在性判断(无需额外依赖,改动最小)

在dispatch请求前先判断Redux中对应的数据源是否已存在,有数据则跳过请求,以Home组件为例修改如下:

function Home(){
 const dispatch = useDispatch();
 const homeData = useSelector((data) => data.homeData);
 React.useEffect(() => {
   // 仅当homeData为空时才发起请求
   if (!homeData?.length) {
     dispatch(getHomeDataAction)
   }
 },[dispatch, homeData])

 return (
   <>
    {
     homeData.map((res) => <span key={res.id}>{res.title}</span>)
    }
   </>
 )
}

About组件按照相同逻辑修改即可,该方案不需要调整路由架构,改造成本最低。

方案2:路由组件持久化(保留组件完整状态)

如果除了避免重复请求之外,还需要保留组件的临时状态(比如表单输入值、滚动位置),可以使用路由缓存方案,React Router v5可通过react-activation库实现KeepAlive功能,路由代码改造如下:

import { AliveScope, KeepAlive } from 'react-activation'
function Rutas(){
  return (
    <Provider store={store}>
      <AliveScope>
        <Router>
         <Switch>
          <Route exact path="/">
            <KeepAlive>
              <Home />
            </KeepAlive>
          </Route>
          <Route path="/about">
            <KeepAlive>
              <About />
            </KeepAlive>
          </Route>
         </Switch>
        </Router>
      </AliveScope>
    </Provider>
  )
}

改造后路由切换时组件不会被卸载,useEffect只会在首次挂载时执行一次,不会重复触发请求。

二、渲染卡顿优化方案

重复请求只是卡顿的诱因,核心问题是大数据量下列表重渲染开销过高,可做以下优化:

  • 给列表项增加唯一key属性:你当前的map方法没有给子元素加key,React Diff时会全量重建DOM,开销极高,按照上面示例代码用数据的唯一字段(比如id)作为key即可大幅降低Diff开销。
  • 采用虚拟滚动:如果单页渲染数据超过100条,可使用react-window实现虚拟滚动,只渲染可视区域内的列表项,DOM节点数量可降低90%以上,渲染耗时会大幅缩短。
  • 组件粒度拆分:将列表项拆分为独立组件,用React.memo包裹,避免无关状态更新触发列表项的不必要重渲染。

内容的提问来源于stack exchange,提问作者Arnel Cariaga Jr.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 19:06:03