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

如何通过Ref实现React-Trello看板Div内的程序化横向滚动?

问题分析与解决方案

你遇到的核心问题是:直接给react-trello的<Board>组件加ref,获取到的是React组件实例而非实际负责滚动的DOM元素,而scrollTo是DOM元素的原生方法,因此调用无效。


错误原因

react-trello的<Board>是自定义React组件,默认情况下,你通过useRef获取的是组件的实例对象(而非渲染后的DOM节点),实例对象并没有scrollTo方法,自然无法触发滚动。


两种可行解决方案

方案1:自定义外层滚动容器(推荐,更可控)

自己包裹一层可横向滚动的容器,直接控制这个容器的滚动行为,不需要依赖react-trello内部DOM结构:

import { useRef } from 'react';
import Board from 'react-trello';

function KanbanBoard() {
  const scrollContainerRef = useRef(null);
  const scrollStep = 200; // 每次滚动的距离,可按需调整

  const scrollRight = () => {
    scrollContainerRef.current?.scrollBy({
      left: scrollStep,
      behavior: 'smooth' // 平滑滚动,可改为'auto'取消平滑
    });
  };

  const scrollLeft = () => {
    scrollContainerRef.current?.scrollBy({
      left: -scrollStep,
      behavior: 'smooth'
    });
  };

  return (
    <div>
      <div style={{ display: 'flex', justifyContent: 'space-between' }}>
        <Icon onClick={scrollLeft}>prev</Icon>
        <Icon onClick={scrollRight}>next</Icon>
      </div>
      {/* 自定义滚动容器 */}
      <div
        ref={scrollContainerRef}
        style={{
          overflowX: 'auto',
          whiteSpace: 'nowrap',
          width: '100%'
        }}
      >
        <Board
          style={{ background: 'none', display: 'inline-block' }}
          components={{ Card: CustomCard }}
          data={data}
          editable={false}
          draggable={false}
          laneDraggable={false}
          cardDraggable={false}
          hideCardDeleteIcon={true}
        />
      </div>
    </div>
  );
}

方案2:定位react-trello内部滚动容器

如果不想额外套容器,可以通过ref找到react-trello内部负责滚动的DOM节点(需要依赖组件内部的DOM结构,可能随版本变化):

import { useRef, useEffect } from 'react';
import Board from 'react-trello';

function KanbanBoard() {
  const boardWrapperRef = useRef(null);
  const scrollContainerRef = useRef(null);
  const scrollStep = 200;

  useEffect(() => {
    // 找到react-trello内部的滚动容器(通常类名为lane-container,可根据实际渲染的DOM调整)
    const scrollContainer = boardWrapperRef.current?.querySelector('.lane-container');
    if (scrollContainer) {
      scrollContainerRef.current = scrollContainer;
    }
  }, []);

  const scrollRight = () => {
    scrollContainerRef.current?.scrollBy({ left: scrollStep, behavior: 'smooth' });
  };

  const scrollLeft = () => {
    scrollContainerRef.current?.scrollBy({ left: -scrollStep, behavior: 'smooth' });
  };

  return (
    <div>
      <div style={{ display: 'flex', justifyContent: 'space-between' }}>
        <Icon onClick={scrollLeft}>prev</Icon>
        <Icon onClick={scrollRight}>next</Icon>
      </div>
      <div ref={boardWrapperRef}>
        <Board
          style={{ background: 'none' }}
          components={{ Card: CustomCard }}
          data={data}
          editable={false}
          draggable={false}
          laneDraggable={false}
          cardDraggable={false}
          hideCardDeleteIcon={true}
        />
      </div>
    </div>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 18:33:01