【问题标题】:synchronise scroll of two react components without using state and actions在不使用状态和动作的情况下同步两个反应组件的滚动
【发布时间】:2016-12-22 20:00:47
【问题描述】:

我试图在 React 中同步两个不同组件的滚动,这样如果我滚动一个组件,另一个组件也会滚动。两者的比例不同,所以我每次都要计算偏移量。

我不想使用状态和动作(我正在使用 redux),因为它会因为重新渲染每个鼠标滚动而损害我的性能(我也尝试过去抖动/节流)。

我有一个包装器组件,它可以像这样呈现另外两个组件:

class Wrapper extends React.Component {
  render() {
    return (
      <div>
        <FirstComponent />
        <SecondComponent />
      </div>
    );
  }
}

我尝试使用ref,但它不适用于自定义组件(我得到undefined),无论如何这看起来像是 react/redux 的反模式。

关于如何在不损害性能并尽可能接近 React/Redux 模式的情况下实现这一目标的任何建议?

【问题讨论】:

    标签: javascript reactjs redux


    【解决方案1】:

    以后有类似问题可以看:react-scroll-sync,用非常复杂的表同步案例拯救了我的工作。

    一个简短的例子如何使用:

    <ScrollSync>
    <div style={{ display: 'flex', position: 'relative', height: 300 }}>
      <ScrollSyncPane>
        <div style={{overflow: 'auto'}}>
          <section style={{ height: 500 }}>
            <h1>Left Pane Content</h1>
            <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ab aperiam doloribus
              dolorum
              est eum eveniet exercitationem iste labore minus, neque nobis odit officiis omnis
              possimus quasi rerum sed soluta veritatis.</p>
          </section>
        </div>
      </ScrollSyncPane>
    
      <ScrollSyncPane>
        <div style={{overflow: 'auto'}}>
          <section style={{ height: 1000 }}>
            <h1>Middle Pane Content</h1>
            <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ab aperiam doloribus
              dolorum
              est eum eveniet exercitationem iste labore minus, neque nobis odit officiis omnis
              possimus quasi rerum sed soluta veritatis.</p>
          </section>
        </div>
      </ScrollSyncPane>
    
    </div>
    </ScrollSync>
    

    【讨论】:

      【解决方案2】:

      我最近创建了this library,可以解决您的问题

      您只需要:

      1. &lt;ScrollSync&gt; 设为您想要与其他节点同步滚动的节点的公共父节点(这是一个使用 React 的新 Context API 的 React 组件)
      2. 然后用&lt;ScrollSyncNode&gt; 包裹每个可滚动节点

      然后同步发生:D

      检查this codesandbox

      【讨论】:

        【解决方案3】:

        不幸的是,React 没有很好的解决方案来处理 refs 之外的 DOM 操作,而且您绝对不希望在每个事件之后引发重新渲染。

        使用ref 绝对可以工作,但请记住,它有时可能会返回undefined,至少在挂载发生之前,因此您需要简单地处理它尚不存在的情况。

        【讨论】:

          【解决方案4】:

          反应。 同步 2 个 div 或表格滚动。没有状态、动作和第三方库。我的解决方案是

          const MyComponent = () => {
          const firstDivRef = useRef();
          const secondDivRef = useRef();
          
          const handleScrollFirst = scroll => {
            secondDivRef.current.scrollTop = scroll.target.scrollTop;
          };
          
          const handleScrollSecond = scroll => {
            firstDivRef.current.scrollTop = scroll.target.scrollTop;
          };
          
          return (
          <div>
            <div onScroll={handleScrollFirst} ref={firstDivRef}>
              The first div (or it can be tbody of a table and etc.)
            </div>
          
            <div onScroll={handleScrollSecond} ref={secondDivRef}>
              The second div
            </div>
          </div>
          );
          };
          

          没有一些样式是行不通的。请查看下面的完整版本以查看样式版本

          现场演示https://codesandbox.io/s/react-custom-scroll-sync-of-2-divs-10xpi

          就是这样! :)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2019-10-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-12-09
            • 2021-04-10
            相关资源
            最近更新 更多