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

SwiperJS在React(NextJS)中双向控制失效并触发TypeError报错

SwiperJS React双向控制报错及多Swiper联动解决方案

一、解决"TypeError: Cannot read properties of undefined (reading 'length')"报错

这个错误的核心原因是Swiper实例未完成初始化就被传入controller属性,在NextJS的SSR环境下,服务端渲染阶段无法生成Swiper实例,直接引用ref会拿到undefined,进而触发读取length的错误。

修复方案:

  1. 使用useState存储初始化后的Swiper实例,避免直接引用未就绪的ref
  2. 通过Swiper的onInit事件捕获实例,确保实例就绪后再传递给controller
  3. 可选:对Swiper组件做SSR禁用处理,彻底规避服务端渲染时的实例缺失问题

示例代码:

import { useRef, useState } from 'react';
import { Swiper, SwiperSlide } from 'swiper/react';
import 'swiper/css';

// 若SSR环境问题仍存在,可改用动态导入禁用SSR
// import dynamic from 'next/dynamic';
// const Swiper = dynamic(() => import('swiper/react').then(mod => mod.Swiper), { ssr: false });
// const SwiperSlide = dynamic(() => import('swiper/react').then(mod => mod.SwiperSlide), { ssr: false });

export default function DualSwiper() {
  const firstRef = useRef(null);
  const secondRef = useRef(null);
  const [firstSwiper, setFirstSwiper] = useState(null);
  const [secondSwiper, setSecondSwiper] = useState(null);

  // 通过onInit事件捕获初始化完成的实例
  const handleFirstInit = (swiper) => setFirstSwiper(swiper);
  const handleSecondInit = (swiper) => setSecondSwiper(swiper);

  return (
    <>
      <Swiper
        ref={firstRef}
        controller={{ control: secondSwiper }}
        onInit={handleFirstInit}
        slidesPerView={1}
        spaceBetween={10}
      >
        <SwiperSlide>滑块1</SwiperSlide>
        <SwiperSlide>滑块2</SwiperSlide>
        <SwiperSlide>滑块3</SwiperSlide>
      </Swiper>

      <Swiper
        ref={secondRef}
        controller={{ control: firstSwiper }}
        onInit={handleSecondInit}
        slidesPerView={1}
        spaceBetween={10}
        style={{ marginTop: '20px' }}
      >
        <SwiperSlide>滑块A</SwiperSlide>
        <SwiperSlide>滑块B</SwiperSlide>
        <SwiperSlide>滑块C</SwiperSlide>
      </Swiper>
    </>
  );
}

二、实现4个Swiper的联动控制

完全可以通过相同逻辑实现多Swiper联动,核心是将每个Swiper的实例存储后,在controller.control中传入除自身外的所有其他Swiper实例数组。

示例代码:

import { useRef, useState } from 'react';
import { Swiper, SwiperSlide } from 'swiper/react';
import 'swiper/css';

export default function MultiSwiper() {
  // 创建4个ref用于绑定每个Swiper组件
  const swiperRefs = Array.from({ length: 4 }, () => useRef(null));
  // 存储所有初始化完成的Swiper实例
  const [swiperInstances, setSwiperInstances] = useState([]);

  // 单个Swiper初始化时更新实例数组
  const handleSwiperInit = (swiper, index) => {
    setSwiperInstances(prev => {
      const newInstances = [...prev];
      newInstances[index] = swiper;
      return newInstances;
    });
  };

  return (
    <div>
      {swiperRefs.map((ref, index) => (
        <Swiper
          key={index}
          ref={ref}
          // 控制除当前Swiper外的所有其他实例
          controller={{ 
            control: swiperInstances.filter((_, i) => i !== index) 
          }}
          onInit={(swiper) => handleSwiperInit(swiper, index)}
          slidesPerView={1}
          spaceBetween={10}
          style={{ marginBottom: '20px' }}
        >
          {[1, 2, 3].map(num => (
            <SwiperSlide key={num}>
              轮播{index + 1} - 滑块{num}
            </SwiperSlide>
          ))}
        </Swiper>
      ))}
    </div>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 11:53:09