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

React.js:为多个滑块div使用useRef时点击仅生效最后一个的解决方法

解决多个滑块共用useRef仅最后一个生效的问题

你遇到的问题根源在于:单个useRef()只能保存一个DOM元素引用。当你给4个div都绑定同一个slider ref时,React会在组件挂载完成后,把最后一个渲染的div元素赋值给slider.current,前面的div引用都会被覆盖,所以无论点击哪个箭头,操作的都是最后一个滑块。

下面提供两种可行的解决方案:

方案一:使用数组形式的useRef

通过useRef([])创建一个数组来存储所有滑块的DOM引用,配合回调ref将每个div存入数组对应索引,点击箭头时传入索引操作指定滑块:

import { useRef } from 'react';
import { BsChevronLeft, BsChevronRight } from 'react-icons/bs';

// 组件内部代码
const slidersRef = useRef([]);

const slideLeft = (index) => {
  const slider = slidersRef.current[index];
  if (slider) {
    slider.scrollLeft -= 500;
  }
};

const slideRight = (index) => {
  const slider = slidersRef.current[index];
  if (slider) {
    slider.scrollLeft += 500;
  }
};

return (
  <>
    <BsChevronLeft onClick={() => slideLeft(0)} />
    <div ref={el => slidersRef.current[0] = el}>
      {/* 渲染你的图片列表 */}
    </div>
    <BsChevronRight onClick={() => slideRight(0)} />

    <BsChevronLeft onClick={() => slideLeft(1)} />
    <div ref={el => slidersRef.current[1] = el}>
      {/* 渲染你的图片列表 */}
    </div>
    <BsChevronRight onClick={() => slideRight(1)} />

    <BsChevronLeft onClick={() => slideLeft(2)} />
    <div ref={el => slidersRef.current[2] = el}>
      {/* 渲染你的图片列表 */}
    </div>
    <BsChevronRight onClick={() => slideRight(2)} />

    <BsChevronLeft onClick={() => slideLeft(3)} />
    <div ref={el => slidersRef.current[3] = el}>
      {/* 渲染你的图片列表 */}
    </div>
    <BsChevronRight onClick={() => slideRight(3)} />
  </>
);

方案二:封装独立的Slider组件(推荐)

把单个滑块的逻辑封装成独立组件,每个组件拥有自己的useRef,避免引用冲突,同时代码更易维护和复用:

第一步:创建Slider子组件

import { useRef } from 'react';
import { BsChevronLeft, BsChevronRight } from 'react-icons/bs';

const Slider = ({ images }) => {
  const sliderRef = useRef(null);

  const slideLeft = () => {
    if (sliderRef.current) {
      sliderRef.current.scrollLeft -= 500;
    }
  };

  const slideRight = () => {
    if (sliderRef.current) {
      sliderRef.current.scrollLeft += 500;
    }
  };

  return (
    <>
      <BsChevronLeft onClick={slideLeft} />
      <div ref={sliderRef}>
        {images.map((image, idx) => (
          <img key={idx} src={image.src} alt={image.alt} />
        ))}
      </div>
      <BsChevronRight onClick={slideRight} />
    </>
  );
};

export default Slider;

第二步:在父组件中复用Slider

import Slider from './Slider';

// 假设你有四组图片数据
const images1 = [{ src: 'img1.jpg', alt: '图1' }, ...];
const images2 = [{ src: 'img2.jpg', alt: '图2' }, ...];
const images3 = [{ src: 'img3.jpg', alt: '图3' }, ...];
const images4 = [{ src: 'img4.jpg', alt: '图4' }, ...];

// 父组件返回内容
return (
  <>
    <Slider images={images1} />
    <Slider images={images2} />
    <Slider images={images3} />
    <Slider images={images4} />
  </>
);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 09:25:29