Framer Motion с React Router

React Router обеспечивает маршрутизацию в приложениях на React, позволяя создавать многостраничные интерфейсы без перезагрузки страницы. Framer Motion добавляет возможности анимации компонентов, включая переходы между страницами. Сочетание этих библиотек позволяет создавать плавные визуальные эффекты при навигации.

Для анимации переходов важно понимать жизненный цикл компонентов и их монтирование/размонтирование. Framer Motion использует компоненты motion и хуки AnimatePresence, чтобы анимации корректно срабатывали при удалении элементов из DOM. React Router в версии 6+ обеспечивает управление маршрутами через компоненты Routes и Route.


Настройка анимации при смене маршрутов

  1. Оборачивание маршрутов в AnimatePresence
import { Routes, Route, useLocation } from 'react-router-dom';
import { AnimatePresence } from 'framer-motion';
import Home from './Home';
import About from './About';

function App() {
  const location = useLocation();

  return (
    
      
        } />
        } />
      
    
  );
}
  • exitBeforeEnter обеспечивает полное завершение анимации выхода предыдущего компонента перед анимацией входа нового.
  • key={location.pathname} гарантирует, что при смене пути Framer Motion распознает, что компонент изменился, и применит анимацию.

Определение анимаций компонентов

Каждый компонент, который участвует в переходе, должен быть обернут в motion.div (или другой motion-компонент):

import { motion } from 'framer-motion';

const pageVariants = {
  initial: { opacity: 0, x: -50 },
  animate: { opacity: 1, x: 0 },
  exit: { opacity: 0, x: 50 },
};

const pageTransition = {
  type: 'tween',
  ease: 'easeInOut',
  duration: 0.5,
};

function Home() {
  return (
    
      

Home Page

); }
  • initial задает стартовое состояние анимации при монтировании компонента.
  • animate отвечает за состояние во время показа.
  • exit описывает анимацию при размонтировании компонента.
  • variants и transition обеспечивают централизованное управление всеми параметрами анимации.

Сложные переходы с сохранением состояния

Для более сложных сценариев, например, когда нужно сохранять состояние компонента при навигации:


  
    } />
    } />
  
  • mode="wait" заменяет устаревший exitBeforeEnter и гарантирует последовательное выполнение анимаций.
  • Внутри компонента можно использовать useState и useEffect, чтобы сохранять состояние между анимациями, а анимации exit и animate обеспечат плавность визуального перехода.

Анимация вложенных маршрутов

Если приложение использует вложенные маршруты, важно правильно обрабатывать анимацию дочерних компонентов:

function Dashboard() {
  return (
    
      

Dashboard

} /> } />
); }
  • Вложенные маршруты могут иметь собственные анимации, но необходимо убедиться, что AnimatePresence находится на уровне, который охватывает все компоненты, участвующие в переходе.
  • Для комплексных интерфейсов можно использовать несколько AnimatePresence с разными ключами (key), чтобы управлять анимацией отдельных блоков независимо.

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

  • Анимации через Framer Motion могут быть ресурсозатратными при большом количестве элементов. Использование exitBeforeEnter или mode="wait" минимизирует лишние перерисовки.
  • Избегать анимации тяжелых компонентов при каждой смене маршрута, вместо этого анимировать только обертку или ключевые элементы.
  • Для больших приложений рекомендуется динамическая подгрузка компонентов (React.lazy + Suspense) с интеграцией Framer Motion для плавного появления загружаемых страниц.

Принципы согласованного UX

  • Все переходы между страницами должны иметь одинаковый стиль анимации (transition, ease), чтобы интерфейс выглядел единым.
  • Анимации exit и animate должны быть симметричными по времени и траектории для визуальной предсказуемости.
  • Использование Framer Motion с React Router позволяет создавать SPA с ощущением настоящего многостраничного сайта без резких визуальных изменений.