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

React Swipeable Views虚拟渲染组件出现抖动、重复加载动画如何解决

问题根因
  • 双重状态更新触发重复渲染:点击Tabs组件时,handleChange回调手动调用setSelectedTab更新状态,后续VirtualizeSwipeableViews检测到索引变化触发onChangeIndex回调,会再次调用setSelectedTab,两次状态更新导致组件重复重载
  • 缺失路由参数监听逻辑:未监听路由params.page的变化,用户通过地址栏跳转、浏览器前进后退操作时,标签状态无法和路由同步
  • slideRenderer分支遗漏:索引为3时对应禁用的logo标签,无匹配的switch分支,可能触发异常渲染
修复方案
  1. 移除Tabs变更回调里的手动状态更新,仅保留路由跳转逻辑,统一通过路由参数同步标签选中状态
  2. 新增useEffect监听路由page参数变化,自动同步更新selectedTab
  3. 补全slideRenderer的switch分支,索引3直接返回null
修复后代码
const App = (props) => {
  
  const { match, history } = props;
  const { params } = match;
  const { page } = params;

  const tabNameToIndex = {
    0: "kaupapa",
    1: "artists",
    2: "tickets",
    4: "info",
    5: "participate",
    6: "gallery",
  };

  const indexToTabName = {
    kaupapa: 0,
    artists: 1,
    tickets: 2,
    info: 4,
    participate: 5,
    gallery: 6,
  };

  const [selectedTab, setSelectedTab] = useState(indexToTabName[page]);

  // 新增:监听路由page参数变化,同步更新选中标签
  useEffect(() => {
    setSelectedTab(indexToTabName[page]);
  }, [page]);

  const handleChange = (event, newIndex) => {
    // 移除手动setSelectedTab,仅做路由跳转
    history.push(`/home/${tabNameToIndex[newIndex]}`);
  };

  const slideRenderer = (params) => {
    const { index } = params;
    let component;

    switch (mod(index, 7)) {
      case 0:
        component = <Kaupapa />;
        break;
      case 1:
        component = <Artists />;
        break;
      case 2:
        component = <Tickets />;
        break;
      // 补全禁用标签的分支
      case 3:
        return null;
      case 4:
        component = <Info />;
        break;
      case 5:
        component = <Participate />;
        break;
      case 6:
        component = <Gallery />;
        break;
      default:
        return null;
    }
    return <>{component}</>;
  };

  const handleChangeIndex = (index) => {
    // 滑动切换时直接跳转路由,由路由同步状态
    history.push(`/home/${tabNameToIndex[index]}`);
  }

  return (
    <>
        <Tabs
          value={selectedTab}
          onChange={handleChange}
        >
          <Tab label="Kaupapa" />
          <Tab label="Artists" />
          <Tab label="Tickets" />
          <Tab
            icon={
              <img
                src={logo}
              ></img>
            }
            disabled
          />
          <Tab label="Info" />
          <Tab label="Participate" />
          <Tab label="Gallery" />
        </Tabs>

      <VirtualizeSwipeableViews
        index={selectedTab}
        onChangeIndex={handleChangeIndex}
        slideRenderer={slideRenderer}
      />
    </>
  );
};

export default App;
优化说明
  • 所有状态变更统一由路由参数作为唯一数据源,避免了多个回调重复更新状态的问题
  • 滑动切换、点击标签切换、路由直接访问三种场景的状态逻辑完全对齐,不会出现状态不一致的问题
  • 补全了缺失的分支逻辑,避免异常渲染导致的额外重绘

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 03:21:01