---
title: "useScroll 用法与示例"
description: "跟踪滚动位置和统计数据。"
canonical: https://reactuse.com/zh-Hans/browser/usescroll/
---

# useScroll

跟踪滚动位置和统计数据

`useScroll` 响应式地跟踪目标元素（或 `window`/`document`）的滚动位置和状态。它返回一个包含 `x` 位置、`y` 位置、`isScrolling` 布尔值、`arrivedState` 对象（`{ top, bottom, left, right }` 布尔值表示是否到达边缘）和 `directions` 对象（表示当前滚动方向）的元组。该 hook 支持节流、偏移配置和滚动及滚动结束事件的回调。

### 使用场景

- 实现滚动相关的 UI，如粘性头部、滚动进度条或"回到顶部"按钮
- 检测用户是否已滚动到容器的顶部或底部（例如用于加载更多内容）
- 跟踪滚动方向以显示或隐藏导航元素

### 注意事项

- **SSR 安全**：在服务端渲染期间位置返回 `0`，`isScrolling` 返回 `false`，到达/方向状态返回默认值。服务端不会附加滚动监听器。
- **节流**：使用 `throttle` 选项限制滚动处理器触发频率，提高复杂滚动 UI 更新的性能。
- **相关 hooks**：参见 `useInfiniteScroll` 了解自动加载更多触发器，`useScrollLock` 了解禁用滚动，以及 `useScrollIntoView` 了解程序化滚动。

## Usage

```tsx live

function Demo() {
  const elementRef = useRef<HTMLDivElement>(null);
  const [x, y, isScrolling, arrivedState, directions] = useScroll(elementRef);
  const { left, right, top, bottom } = useMemo(
    () => arrivedState,
    [arrivedState],
  );
  const {
    left: toLeft,
    right: toRight,
    top: toTop,
    bottom: toBottom,
  } = useMemo(() => directions, [directions]);

  const absoluteStyle: CSSProperties = {
    paddingTop: "0.25rem",
    paddingBottom: "0.25rem",
    paddingLeft: "0.5rem",
    paddingRight: "0.5rem",
    position: "absolute",
  };
  return (
    <div style={{ display: "flex" }}>
      <div
        ref={elementRef}
        style={{
          width: 300,
          height: 300,
          margin: "auto",
          borderRadius: "0.25rem",
          overflow: "scroll",
        }}
      >
        <div style={{ width: 500, height: 400, position: "relative" }}>
          <div
            style={{
              ...absoluteStyle,
              top: "0rem",
              left: "0rem",
            }}
          >
            左上角
          </div>
          <div
            style={{
              ...absoluteStyle,
              bottom: "0rem",
              left: "0rem",
            }}
          >
            左下角
          </div>
          <div
            style={{
              ...absoluteStyle,
              top: "0rem",
              right: "0rem",
            }}
          >
            右上角
          </div>
          <div
            style={{
              ...absoluteStyle,
              bottom: "0rem",
              right: "0rem",
            }}
          >
            右下角
          </div>
          <div
            style={{
              ...absoluteStyle,
              top: "33.33333%",
              left: "33.33333%",
            }}
          >
            滚动区域
          </div>
        </div>
      </div>
      <div
        style={{
          width: 280,
          margin: "auto",
          paddingLeft: "1rem",
          display: "flex",
          flexDirection: "column",
          gap: 5,
        }}
      >
        <div>
          位置: {x.toFixed(1)}, {y.toFixed(1)}
        </div>
        <div>正在滚动: {JSON.stringify(isScrolling)}</div>
        <div>到达顶部: {JSON.stringify(top)}</div>
        <div>到达右侧: {JSON.stringify(right)}</div>
        <div>到达底部: {JSON.stringify(bottom)}</div>
        <div>到达左侧: {JSON.stringify(left)}</div>
        <div>向上滚动: {JSON.stringify(toTop)}</div>
        <div>向右滚动: {JSON.stringify(toRight)}</div>
        <div>向下滚动: {JSON.stringify(toBottom)}</div>
        <div>向左滚动: {JSON.stringify(toLeft)}</div>
      </div>
    </div>
  );
};

```

%%API%%