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

React useState钩子异常:调用setActiveSlide后Swiper实例story变为null

为什么调用setActiveSlide后Swiper实例story会变成null?

这个问题我之前也碰到过,核心原因是你用普通变量story保存Swiper实例,而React组件重渲染时会重置这个变量。

当你调用setActiveSlide更新组件状态activeSlide时,React会触发组件的重新渲染——整个Slideshow组件函数会再次执行一遍。这时候你写的var story = null;会重新运行,直接把之前已经创建好的Swiper实例覆盖成了null,所以后续点击「上一张」「下一张」按钮时,调用story.slidePrev()自然就会抛出Cannot read property 'slideNext' of null的错误。

要解决这个问题,你需要用React的useRef来保存Swiper实例,因为useRef创建的引用对象在组件的整个生命周期内都会保持稳定,不会因为组件重渲染而被重置。

下面是修改后的完整代码:

import React, { useState, useEffect, useRef } from "react";
import Swiper from "swiper";

const Slideshow = props => {
  const swiper = useRef();
  // 用useRef保存Swiper实例,替代普通变量
  const story = useRef(null);
  const [activeSlide, setActiveSlide] = useState("");

  useEffect(() => {
    // 将实例赋值给story.current
    story.current = new Swiper(swiper.current, {
      loop: false,
      speed: 1100
    });
  }, []);

  const prevSlide = () => {
    setActiveSlide("PREV");
    // 通过current属性访问持久化的实例
    story.current.slidePrev();
  };

  const nextSlide = () => {
    setActiveSlide("NEXT");
    story.current.slideNext();
  };

  return (
    <div className="container-story" ref={swiper}>
      <div className="container-story-wrapper swiper-wrapper">
        {props.children}
      </div>
      <div className="navigation">
        <button onClick={prevSlide}> Previous </button>
        <button onClick={nextSlide}> Next </button>
        {activeSlide}
      </div>
      <div className="lightbox-container"></div>
    </div>
  );
};

export default Slideshow;

简单梳理下关键修改点:

  • 把var story = null;替换为const story = useRef(null);,用useRef创建一个跨渲染周期的持久化引用
  • 在useEffect初始化逻辑中,将Swiper实例赋值给story.current
  • 在按钮点击函数里,通过story.current调用Swiper的滑动方法

这样无论组件因为状态更新重渲染多少次,story.current都会保留住之前创建的Swiper实例,不会再出现null的问题了。


内容的提问来源于stack exchange,提问作者Gunther von Goetzen Sanchez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 09:22:39