React компоненты

Для интеграции Smooth Scroll в проект на React чаще всего используют библиотеку smooth-scroll из npm. Установка производится командой:

npm install smooth-scroll

После установки библиотеку можно импортировать в компонент, где планируется использовать плавную прокрутку:

import SmoothScroll from 'smooth-scroll';

Инициализация Smooth Scroll происходит в методе useEffect для функциональных компонентов или в componentDidMount для классовых компонентов, чтобы доступ к DOM был уже возможен:

import { useEffect } from 'react';

function App() {
  useEffect(() => {
    const scroll = new SmoothScroll('a[href*="#"]', {
      speed: 800,
      speedAsDuration: true,
      offset: 50
    });
    return () => scroll.destroy();
  }, []);

  return (
    <div>
      <nav>
        <a href="#section1">Раздел 1</a>
        <a href="#section2">Раздел 2</a>
      </nav>
      <section id="section1" style={{ height: '100vh' }}>Секция 1</section>
      <section id="section2" style={{ height: '100vh' }}>Секция 2</section>
    </div>
  );
}

Ключевые параметры настройки

  • speed – скорость прокрутки в миллисекундах. Определяет, за сколько времени произойдет перемещение к цели.
  • speedAsDuration – если true, значение speed воспринимается как длительность, а не как скорость движения.
  • offset – смещение от верхнего края окна. Полезно при наличии фиксированной шапки.
  • easing – функция плавности движения. Можно передавать стандартные CSS-функции типа easeInOutCubic или создавать собственные.
const scroll = new SmoothScroll('a[href*="#"]', {
  speed: 600,
  offset: 70,
  easing: 'easeInOutQuad'
});

Интеграция с динамическими компонентами

В React часто используются динамические списки или ленивое рендеринг. В таких случаях необходимо повторно инициализировать Smooth Scroll после того, как элементы появились в DOM. Например:

import { useEffect, useState } from 'react';

function DynamicList() {
  const [items, setItems] = useState([]);

  useEffect(() => {
    const scroll = new SmoothScroll('a[href*="#"]', { speed: 500 });
    return () => scroll.destroy();
  }, [items]);

  return (
    <div>
      <button onCl ick={() => setItems([...items, `Элемент ${items.length + 1}`])}>
        Добавить элемент
      </button>
      <ul>
        {items.map((item, index) => (
          <li key={index}><a href={`#item${index}`}>{item}</a></li>
        ))}
      </ul>
      {items.map((item, index) => (
        <section id={`item${index}`} key={index} style={{ height: '100vh' }}>
          {item}
        </section>
      ))}
    </div>
  );
}

Использование Ref для прокрутки к конкретному элементу

Иногда требуется программно прокрутить к элементу, не используя якорь <a href>. В React можно использовать ref и метод animateScroll:

import { useRef, useEffect } from 'react';
import SmoothScroll from 'smooth-scroll';

function ScrollToRefExample() {
  const sectionRef = useRef(null);

  useEffect(() => {
    const scroll = new SmoothScroll();
    return () => scroll.destroy();
  }, []);

  const scrollToSection = () => {
    if (sectionRef.current) {
      SmoothScroll.animateScroll(sectionRef.current, null, {
        speed: 700,
        offset: 60
      });
    }
  };

  return (
    <div>
      <button onCl ick={scrollToSection}>Перейти к секции</button>
      <section ref={sectionRef} style={{ height: '100vh' }}>Целевая секция</section>
    </div>
  );
}

Совмещение с React Router

При использовании react-router-dom часто требуется плавная прокрутка при переходе между страницами. Для этого используют useEffect в компоненте-обертке маршрутов:

import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
import SmoothScroll from 'smooth-scroll';

function ScrollToTop() {
  const { pathname, hash } = useLocation();

  useEffect(() => {
    const scroll = new SmoothScroll();
    if (hash) {
      scroll.animateScroll(document.querySelector(hash), null, { speed: 600 });
    } else {
      scroll.animateScroll(0, null, { speed: 600 });
    }
    return () => scroll.destroy();
  }, [pathname, hash]);

  return null;
}

Производительность и оптимизация

  • destroy() – всегда уничтожать экземпляр Smooth Scroll при размонтировании компонентов, чтобы избежать утечек памяти.
  • Селекторы – использовать точные селекторы вместо глобальных 'a[href*="#"]' для больших приложений.
  • Lazy Load и динамика – пересоздавать экземпляр Smooth Scroll после динамического рендеринга элементов, которые должны быть прокручены.

Расширение возможностей

Smooth Scroll позволяет:

  • Настраивать кривые ускорения через easing.
  • Плавно прокручивать на определенное смещение.
  • Работать с произвольными DOM-элементами через animateScroll.
  • Сочетать с анимациями при прокрутке, например через библиотеки типа framer-motion.

Этот подход обеспечивает плавный UX при работе с длинными страницами, одностраничными приложениями и динамическими списками, полностью интегрированными в архитектуру React.