Интеграция с React

Shepherd.js — это библиотека для создания интерактивных пошаговых руководств по интерфейсу. В контексте React важно учитывать особенности управления состоянием компонентов и жизненным циклом, чтобы обеспечить корректное создание, обновление и уничтожение туров.

Установка и подключение

Для работы с Shepherd.js в React достаточно установить пакет через npm или yarn:

npm install shepherd.js
# или
yarn add shepherd.js

Импорт библиотек в компонент React выполняется следующим образом:

import Shepherd from 'shepherd.js';
import 'shepherd.js/dist/css/shepherd.css';

CSS обязательно подключается, чтобы подсказки отображались корректно с правильными стилями.

Создание тура в функциональном компоненте

В функциональных компонентах React рекомендуется использовать хуки для управления состоянием тура. Обычно создаётся объект тура через useRef или useState и инициализируется один раз через useEffect.

import React, { useEffect, useRef } from 'react';
import Shepherd from 'shepherd.js';

function TourComponent() {
  const tourRef = useRef(null);

  useEffect(() => {
    const tour = new Shepherd.Tour({
      defaultStepOptions: {
        scrollTo: true,
        cancelIcon: {
          enabled: true
        },
        classes: 'shepherd-theme-arrows'
      },
      useModalOverlay: true
    });

    tour.addStep({
      id: 'intro',
      text: 'Добро пожаловать в наше приложение!',
      attachTo: { element: '.header', on: 'bottom' },
      buttons: [
        {
          text: 'Далее',
          action: tour.next
        }
      ]
    });

    tour.addStep({
      id: 'feature',
      text: 'Здесь вы можете видеть основные функции.',
      attachTo: { element: '.feature', on: 'top' },
      buttons: [
        {
          text: 'Назад',
          action: tour.back
        },
        {
          text: 'Закрыть',
          action: tour.complete
        }
      ]
    });

    tourRef.current = tour;

    return () => {
      tour.complete();
    };
  }, []);

  return (
    <div>
      <button onCl ick={() => tourRef.current.start()}>Начать тур</button>
      <div className="header">Заголовок</div>
      <div className="feature">Особенности</div>
    </div>
  );
}

Ключевые моменты:

  • Использование useRef предотвращает повторную инициализацию тура при каждом рендере.
  • Возврат функции очистки в useEffect гарантирует уничтожение тура при размонтировании компонента, предотвращая утечки памяти и ошибки при повторном монтировании.
  • Все шаги добавляются через метод addStep, каждый шаг может содержать текст, кнопки и привязку к элементу интерфейса.

Управление состоянием и динамические шаги

В реальных приложениях шаги тура могут зависеть от состояния компонента или данных из API. Shepherd.js позволяет добавлять шаги динамически.

useEffect(() => {
  if (!tourRef.current) return;

  const dynamicStep = {
    id: 'user-profile',
    text: `Ваш текущий уровень: ${user.level}`,
    attachTo: { element: '.profile', on: 'right' },
    buttons: [
      { text: 'Назад', action: tourRef.current.back },
      { text: 'Закрыть', action: tourRef.current.complete }
    ]
  };

  tourRef.current.addStep(dynamicStep);
}, [user.level]);

Особенности:

  • Шаг добавляется только после того, как данные готовы, что предотвращает ошибки доступа к несуществующим элементам.
  • React-хуки useEffect с зависимостями позволяют реагировать на изменения состояния и автоматически обновлять шаги.

Использование Shepherd.js с контекстом и глобальными турами

Для крупных приложений удобно создавать глобальный контекст тура, чтобы любой компонент мог запускать или изменять шаги тура.

import React, { createContext, useContext, useRef } from 'react';
import Shepherd from 'shepherd.js';

const TourContext = createContext(null);

export function TourProvider({ children }) {
  const tourRef = useRef(new Shepherd.Tour({ useModalOverlay: true }));

  return (
    <TourContext.Provider value={tourRef.current}>
      {children}
    </TourContext.Provider>
  );
}

export function useTour() {
  return useContext(TourContext);
}

В компоненте можно вызывать:

const tour = useTour();
tour.addStep({ /* шаг */ });
tour.start();

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

Стилизация и темы

Shepherd.js предоставляет встроенные темы, но их можно кастомизировать через CSS. Для React удобно создавать отдельный файл стилей или использовать CSS-in-JS решения:

.shepherd-theme-arrows {
  background-color: #fff;
  color: #333;
  border-radius: 6px;
  box-shadow: 0 0 10px rgba(0,0,0,0.2);
}

.shepherd-button {
  background-color: #007bff;
  color: white;
  border: none;
  padding: 5px 12px;
  border-radius: 4px;
  cursor: pointer;
}

Подключение стилей через import './tour.css'; обеспечивает единообразный внешний вид всех шагов тура.

Анимации и дополнительные возможности

  • scrollTo: автоматически прокручивает страницу к целевому элементу.
  • useModalOverlay: затемняет фон и фокусирует внимание пользователя на шаге.
  • attachTo: позволяет точно позиционировать подсказку относительно элемента.
  • advanceOn: шаг может переходить по событию, например, клику или навигации.
tour.addStep({
  id: 'submit-button',
  text: 'Нажмите здесь, чтобы отправить форму',
  attachTo: { element: '.submit-btn', on: 'left' },
  advanceOn: { selector: '.submit-btn', event: 'click' }
});

Использование advanceOn особенно полезно для интерактивных шагов, где пользователь должен выполнить конкретное действие.

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

  • Инициализировать туры один раз при монтировании компонента.
  • Удалять шаги и завершать тур при размонтировании компонента.
  • Для больших приложений использовать контекст для повторного использования тура.
  • Динамически добавлять шаги только после готовности DOM-элементов, чтобы избежать ошибок.

Эти подходы обеспечивают стабильную работу Shepherd.js в среде React и позволяют создавать гибкие и интерактивные пошаговые руководства, полностью интегрированные с современным интерфейсом.