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

React图片轮播setTimeout执行时报Cannot read properties of undefined (reading 'style')错误

报错原因

出现TypeError: Cannot read properties of undefined (reading 'style')是因为代码访问ImgContainer.current.style的时候,ImgContainer.current为undefined,触发的场景有以下几个:

  • 你没有把setTimeout放到副作用钩子中,组件每次重渲染都会生成新的5秒定时器,旧定时器没有被清理,当定时器触发时可能组件已经卸载、或者DOM还未完成挂载,ref还没有绑定到对应的div元素上
  • 你没有对ref.current做非空校验,只要ref绑定失败就会直接抛出异常
  • 另外你的代码还存在其他逻辑问题:handleNext中重复调用setposition会导致position计数错误,没有做轮播边界判断会出现滑到空白区域的问题,也没有实现用户操作后重置5秒倒计时的需求逻辑
修复方案

调整后的完整代码如下,所有问题都已修复:

import React, { useRef, useState, useEffect } from 'react'
import BeforeIcon from "../assests/before.svg"
import NextIcon from "../assests/next.svg"

import Banner1 from "../assests/banner1.jpg"
import Banner2 from "../assests/banner2.jpg"

import "../styles/banner.css"

export default function Banner() {
  const ImgContainer = useRef(null)
  const timerRef = useRef(null)
  // 对应轮播图的总数量,可根据实际情况调整
  const TOTAL_SLIDES = 7
  const [position, setPosition] = useState(0)
  const [w, setW] = useState(window.innerWidth)

  // 重置自动轮播倒计时
  const resetAutoTimer = () => {
    if (timerRef.current) clearTimeout(timerRef.current)
    timerRef.current = setTimeout(() => {
      handleNext()
    }, 5000)
  }

  const handleNext = () => {
    // 边界判断:滑到最后一张后回到第一张
    const newPosition = position === TOTAL_SLIDES - 1 ? 0 : position + 1
    const move = w * newPosition
    setPosition(newPosition)
    // 非空校验后再操作DOM,避免报错
    if (ImgContainer.current) {
      ImgContainer.current.style.transform = `translateX(-${move}px)`
      ImgContainer.current.style.transition = "transform 1s"
    }
    // 用户主动操作后重置自动轮播
    resetAutoTimer()
  }

  const handleBefore = () => {
    // 边界判断:滑到第一张后回到最后一张
    const newPosition = position === 0 ? TOTAL_SLIDES - 1 : position - 1
    const move = w * newPosition
    setPosition(newPosition)
    if (ImgContainer.current) {
      ImgContainer.current.style.transform = `translateX(-${move}px)`
      ImgContainer.current.style.transition = "transform 1s"
    }
    resetAutoTimer()
  }

  useEffect(() => {
    // 初始化自动轮播
    resetAutoTimer()
    // 监听窗口宽度变化,适配窗口缩放场景
    const handleResize = () => setW(window.innerWidth)
    window.addEventListener('resize', handleResize)
    // 组件卸载时清理定时器和监听事件,避免内存泄漏和无效执行
    return () => {
      if (timerRef.current) clearTimeout(timerRef.current)
      window.removeEventListener('resize', handleResize)
    }
  }, [position])

  return (
      <section>
          <button onClick={handleBefore}><img src={BeforeIcon} alt="" className="button right"/></button>
              <div ref={ImgContainer} className="imgcontainer">
                  <img src={Banner2} alt="" className="bannerimg"/>
                  <img src={Banner2} alt="" className="bannerimg"/>
                  <img src={Banner2} alt="" className="bannerimg"/>
                  <img src={Banner2} alt="" className="bannerimg"/>
                  <img src={Banner1} alt="" className="bannerimg"/>
                  <img src={Banner1} alt="" className="bannerimg"/>
                  <img src={Banner1} alt="" className="bannerimg"/>
              </div>
          <button onClick={handleNext}><img src={NextIcon} alt="" className="button left"/></button>
      </section>
  )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 03:36:04