Анимация входа и выхода компонентов React с помощью Framer Motion

Почему это важно
Анимация входа и выхода делает интерфейс более отзывчивым и понятным пользователю. Проблема в том, что React при скрытии компонента удаляет его из DOM, и у него нет времени проиграть анимацию выхода. Framer Motion решает эту задачу, позволяя компоненту проиграть анимацию показа и скрытия перед удалением из DOM.
Краткое определение
Framer Motion — production‑готовая библиотека анимаций для React. Она предоставляет компонент motion, утилиты для управления состояниями анимации и API для переходов, easing и событий.
Что пригодится перед началом
- Node.js и npm/yarn установлены.
- Базовые знания React и хуков (useState).
- Проект, созданный через Vite, Create React App или аналог.
Создание проекта (быстро)
Если у вас ещё нет проекта, создайте его с Vite:
yarn create vite my-app --template react
cd my-app
yarn
yarn devЗамените yarn на npm, если предпочитаете npm. Команды приведены как пример — используйте подходящий для вас менеджер пакетов.
Установка Framer Motion
npm install framer-motionИли
yarn add framer-motionЭто добавит framer-motion в зависимости вашего проекта.
Базовый пример: анимация при появлении и исчезновении
Обёрните элемент в motion и поместите внутри AnimatePresence. Ниже — рабочий и исправленный пример компонента App.jsx с кнопкой, которая переключает видимость.
import { AnimatePresence, motion } from "framer-motion";
import { useState } from "react";
function App() {
const [isVisible, setIsVisible] = useState(true);
const toggleVisibility = () => setIsVisible(prev => !prev);
return (
<>
{isVisible && (
Отправлено!
)}
>
);
}
export default App;Пояснения:
- initial задаёт стартовые свойства при первом рендере (в нашем примере элемент смещён влево и невидим);
- animate описывает целевые значения при входе;
- exit — свойства при выходе перед удалением из DOM;
- AnimatePresence гарантирует, что exit-анимация отработает перед удалением узла.
Важно: если вы рендерите несколько элементов в списке, убедитесь, что у каждого есть уникальный key. AnimatePresence опирается на ключи для определения присутствия.
Добавление easing и настройки перехода
Easing управляет скоростью анимации во времени. Framer Motion поддерживает как предопределённые кривые, так и произвольные кривые Безье. Пример с ease и duration:
Отправлено!
Примечание: вместо строкового имени easing вы можете передать массив чисел кривой Безье или функцию.
Частые приёмы и паттерны
Варианты (variants)
Вместо повторяющихся initial/animate/exit удобно определять variants:
const boxVariants = {
hidden: { x: -100, opacity: 0 },
visible: { x: 0, opacity: 1 },
exit: { x: -100, opacity: 0 }
};
...
Variants упрощают организацию анимаций, особенно для вложенных компонентов и stagger‑эффектов.
Анимация списков
Используйте staggerChildren и animate на контейнере, а для элементов — variants. Не забудьте key на каждом элементе.
layout и layoutId
Для плавных переходов между позициями элементов (reflow) применяйте проп layout. Для анимации перемещения между разными маршрутам используйте layoutId.
Когда Framer Motion — лишний инструмент
- Простые hover‑эффекты и микровзаимодействия часто проще сделать на CSS.
- Если вам критичен минимальный размер бандла и анимаций немного — можно обойтись CSS.
Альтернативы
- Чистый CSS (transition/animation) — лёгкий вариант для простых эффектов.
- React Transition Group — библиотека с низкоуровневым контролем входа/выхода.
- GreenSock (GSAP) — мощный инструмент для сложных анимаций и таймингов.
Практические советы и эвристики
- Минимизируйте количество одновременно анимируемых свойств (transform + opacity — лучший выбор для производительности).
- Анимируйте transform вместо left/top — так рендер происходит быстрее.
- Тестируйте на мобильных устройствах: сложные анимации могут нагружать CPU.
- Давайте пользователям выбор: уважайте prefers-reduced-motion CSS-медиа‑запрос.
Чек-листы по ролям
Для разработчика
- Установлен framer-motion в package.json.
- Каждый анимируемый элемент имеет уникальный key.
- Используются transform и opacity для анимации.
- AnimatePresence окружает условно рендеримые элементы.
- Добавлена поддержка prefers-reduced-motion.
Для дизайнера
- Описаны желаемые кривые easing и длительности.
- Предоставлены макеты переходов (micro‑interactions).
- Проверено поведение на разных скоростях анимации.
Для QA
- Проверен порядок анимаций при быстром переключении.
- Проверено поведение при медленных сетях и слабых девайсах.
- Проверено соответствие accessibility требованиям.
Критерии приёмки
- Анимация входа и выхода проигрывается корректно при клике на кнопку.
- Компонент удаляется из DOM только после завершения exit‑анимации.
- Нет заметного «дерганья» или внезапного появления.
- Производительность на мобильных устройствах приемлема.
Тестовые случаи (приёмочные тесты)
- Клик по кнопке показывает и скрывает элемент — анимация проигрывается при каждом действии.
- Быстрое многократное переключение не ломает порядок анимаций и не создаёт дублирующих элементов.
- При включённом prefers-reduced-motion анимации либо упрощаются, либо отключаются.
Мини‑методология внедрения анимации (шаги)
- Определите, нужен ли эффект (UX‑цель).
- Выберите способ: CSS или Framer Motion.
- Прототипируйте ключевые переходы в небольшой компонент.
- Протестируйте на целевых устройствах.
- Внедрите в продакшн с мониторингом производительности.
Примеры ошибок и когда это не работает
- Отсутствие unique key для списка — AnimatePresence не сможет корректно детектировать элементы.
- Жёсткие inline‑стили, конфликтующие с motion‑props.
- Попытка анимировать свойства, которые не поддерживают аппаратное ускорение (например, height без transform) — возможны просадки.
Советы по совместимости и миграции
- Если переходите с CSS: начните с небольших компонентов, повторно используйте существующие классы стилей.
- Если у вас SSR, убедитесь, что начальное состояние компонента (initial) не вызывает мерцания интерфейса.
- Для больших приложений можно lazy‑load framer-motion только на страницах с анимациями.
Безопасность и уважение приватности
Анимации не отправляют данных и не меняют политику приватности. Убедитесь, что анимации не препятствуют доступности: используйте semantic HTML и aria‑атрибуты при необходимости.
Мермаид‑схема: выбор между CSS и Framer Motion
flowchart TD
A[Нужна анимация?] --> B{Простая или сложная?}
B -- простая --> C[Используйте CSS]
B -- сложная --> D[Фреймворк]
D --> E{Нужны переходы между состояниями и появление/удаление компонента?}
E -- да --> F[Используйте Framer Motion]
E -- нет --> CКраткий шпаргалка (cheat sheet)
- initial — стартовое состояние
- animate — целевое состояние
- exit — состояние при удалении
- transition — настройки длительности и easing
- variants — наборы состояний для переиспользования
- AnimatePresence — компонент, который позволяет проигрывать exit
Пример уделённый вниманию доступности
Добавьте уважение к системным настройкам для пользователей, которым не нравится анимация:
@media (prefers-reduced-motion: reduce) {
.animated { transition: none !important; }
}И в React можно условно отключать анимации, если detectPrefersReduceMotion() вернул true.
Итог
Framer Motion — мощный и интуитивный инструмент для создания плавных переходов в React. Он особенно полезен, когда нужно анимировать появление и скрытие компонентов, управлять сложными последовательностями и синхронизировать дочерние анимации. Для простых эффектов по‑прежнему достаточно CSS.
Ключевые рекомендации: используйте transform/opacity для производительности, давайте уникальные key элементам в списке, оборачивайте условно рендеримые блоки в AnimatePresence и уважайте prefers-reduced-motion.
Важно: перед развёртыванием протестируйте на реальных устройствах и проверьте поведение при быстрых переключениях состояния.
Похожие материалы
RDP: полный гид по настройке и безопасности
Android как клавиатура и трекпад для Windows
Советы и приёмы для работы с PDF
Calibration в Lightroom Classic: как и когда использовать
Отключить Siri Suggestions на iPhone