Для работы с Intro.js в приложениях на React
рекомендуется использовать официальную библиотеку intro.js
вместе с пакетами типов для TypeScript (если проект типизирован).
Установка производится через npm:
npm install intro.js
npm install --save-dev @types/intro.js
После установки необходимо импортировать стили Intro.js в корневой файл приложения или в компонент, где будет использоваться библиотека:
import 'intro.js/introjs.css';
import introJs from 'intro.js';
Создание тура в React-компоненте выполняется через вызов метода
introJs(). Обычно инициализацию выполняют в обработчике
событий или в useEffect, чтобы контролировать момент
запуска:
import React, { useEffect } from 'react';
import introJs from 'intro.js';
const TourComponent = () => {
useEffect(() => {
const intro = introJs();
intro.setOptions({
steps: [
{
element: '#step1',
intro: 'Это первый шаг тура',
},
{
element: '#step2',
intro: 'Это второй шаг тура',
},
{
element: '#step3',
intro: 'Последний шаг',
},
],
showProgress: true,
showBullets: false,
exitOnOverlayClick: false,
});
intro.start();
}, []);
return (
<div>
<div id="step1">Элемент 1</div>
<div id="step2">Элемент 2</div>
<div id="step3">Элемент 3</div>
</div>
);
};
export default TourComponent;
Ключевые моменты:
element — CSS-селектор элемента, к которому
привязывается шаг.intro — текст подсказки для шага.setOptions позволяет конфигурировать внешний вид,
управление навигацией, прогрессбар, кнопки и поведение при клике на
оверлей.React позволяет динамически управлять шагами и состоянием тура. Часто
используют useState для контроля видимости тура:
import React, { useState } from 'react';
import introJs from 'intro.js';
const DynamicTour = () => {
const [tourActive, setTourActive] = useState(false);
const startTour = () => {
const intro = introJs();
intro.setOptions({
steps: [
{ element: '#step1', intro: 'Первый шаг' },
{ element: '#step2', intro: 'Второй шаг' },
],
});
intro.start().onexit(() => setTourActive(false));
setTourActive(true);
};
return (
<div>
<button onCl ick={startTour}>Начать тур</button>
<div id="step1">Элемент 1</div>
<div id="step2">Элемент 2</div>
</div>
);
};
Особенности управления:
onexit позволяет сбрасывать состояние при закрытии
тура.Intro.js одинаково совместим с функциональными и классовыми
компонентами. В классах рекомендуется инициализировать тур в
componentDidMount:
import React, { Component } from 'react';
import introJs from 'intro.js';
class TourClassComponent extends Component {
componentDidMount() {
this.intro = introJs();
this.intro.setOptions({
steps: [
{ element: '#step1', intro: 'Шаг 1' },
{ element: '#step2', intro: 'Шаг 2' },
],
});
this.intro.start();
}
render() {
return (
<div>
<div id="step1">Элемент 1</div>
<div id="step2">Элемент 2</div>
</div>
);
}
}
export default TourClassComponent;
Шаги можно формировать динамически на основе состояния или props. Это удобно для приложений, где интерфейс меняется в зависимости от данных:
const steps = [
{ element: '#dynamic1', intro: `Привет, ${user.name}` },
{ element: '#dynamic2', intro: `У вас ${notifications.length} уведомлений` },
];
introJs().setOptions({ steps }).start();
Intro.js позволяет кастомизировать внешний вид через CSS и опции конфигурации:
tooltipClass — добавить кастомный класс для
тултипа.highlightClass — изменить стиль подсвечиваемого
элемента.overlayOpacity — прозрачность затемнения.position — расположение подсказки (top,
bottom, left, right,
auto).Пример с кастомным классом:
introJs().setOptions({
steps: [
{ element: '#step1', intro: 'Тур с кастомным стилем', tooltipClass: 'my-tooltip' },
],
}).start();
CSS для my-tooltip:
.my-tooltip {
background-color: #1a73e8;
color: white;
font-weight: bold;
border-radius: 8px;
}
Intro.js предоставляет события, которые удобно использовать в React:
onbeforechange — перед сменой шага.onchange — после смены шага.oncomplete — завершение тура.onexit — выход из тура.Пример:
introJs()
.onbeforechange(targetElement => console.log('Сменился шаг', targetElement))
.oncomplete(() => console.log('Тур завершён'))
.start();
В React-приложениях с роутером (например, react-router)
важно запускать тур после полной загрузки целевого маршрута:
import { useLocation } from 'react-router-dom';
const TourOnRoute = () => {
const location = useLocation();
useEffect(() => {
if (location.pathname === '/dashboard') {
introJs().setOptions({ steps: [{ element: '#dashboard-step', intro: 'Добро пожаловать!' }] }).start();
}
}, [location]);
return null;
};
Это гарантирует, что элементы, к которым привязываются шаги, уже присутствуют в DOM.
Intro.js можно загружать динамически с помощью
React.lazy или import(), чтобы уменьшить
размер основного бандла:
const startTour = async () => {
const introJsModule = await import('intro.js');
introJsModule.default().setOptions({ steps: [{ element: '#step', intro: 'Ленивая загрузка' }] }).start();
};
Такой подход особенно полезен для крупных приложений, где туры нужны не на всех страницах.