Гид по технологиям

Перенаправление пользователей в React: Navigate и useNavigate

5 min read React Обновлено 19 Dec 2025
Перенаправление в React: Navigate и useNavigate
Перенаправление в React: Navigate и useNavigate

Белая стрелка на красном фоне

TL;DR

Кратко: в React Router v6 перенаправления выполняют компонент Navigate и хук useNavigate. Navigate удобен для декларативной защиты маршрутов; useNavigate — для императивной навигации после действий (например, после логина). Для лучшего UX сохраняйте страницу, с которой пришёл пользователь, и возвращайте его обратно после успешной аутентификации.

Важно: используйте React Context или менеджер состояния и храните токен/сессию безопасно (в реальном приложении — не в localStorage без дополнительных мер).


Зачем это нужно

При создании веб-приложений приватные страницы (панель администратора, профиль, дашборд) должны быть доступны только аутентифицированным пользователям. Если неаутентифицированный пользователь пытается попасть на такой маршрут, приложение должно перенаправить его на страницу входа и, после успешного входа, вернуть на исходную страницу.

Ниже собраны примеры, подходы и практические рекомендации по реализации этого сценария в React с React Router v6.

Создайте приложение React

В React Router v6 есть два основных способа перенаправления: компонент Navigate и хук useNavigate(). Для демонстрации создайте приложение с помощью create-react-app:

        `npx create-react-app react-redirect  
`
    

Примечание: в production-проектах создавайте проект с необходимой сборкой (Vite, Next.js или др.), если нужна SSR или более быстрая разработка.

Создаём страницу входа (Login)

В простых примерах часто используют массив объектов как базу пользователей. Вот один из исходных примеров из статьи:

        `import { useState } from "react";  
import Dashboard from "./Dashboard";  
  
const Login = () => {  
  const [username, setusername] = useState("");  
  const [password, setpassword] = useState("");  
  const [authenticated, setauthenticated] = useState(localStorage.getItem(localStorage.getItem("authenticated")|| false));  
  const users = [{ username: "Jane", password: "testpassword" }];  
  const handleSubmit = (e) => {  
    e.preventDefault()  
    const account = users.find((user) => user.username === username);  
    if (account && account.password === password) {  
        setauthenticated(true)  
        localStorage.setItem("authenticated", true);  
    }  
  };  
  return (  
    
      

Welcome Back

      
       setusername(e.target.value)}       />        setpassword(e.target.value)}       />              
    
  ) }; } export default Login; `

Этот пример демонстрирует базовую идею, но содержит ошибки и анти-паттерны (например, некорректное чтение localStorage и хранение аутентификации в localStorage без проверки). Ниже — улучшённый и безопаснее организованный пример, который можно использовать как шаблон для обучения.

Рекомендуемый пример Login (упрощённо для демо)

import { useState } from "react";
import { useNavigate, useLocation } from "react-router-dom";

const demoUsers = [{ username: "Jane", password: "testpassword" }];

export default function Login() {
  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");
  const navigate = useNavigate();
  const location = useLocation();
  // from — страница, на которую хотели попасть
  const from = location.state?.from?.pathname || "/dashboard";

  const handleSubmit = (e) => {
    e.preventDefault();
    const account = demoUsers.find((u) => u.username === username);
    if (account && account.password === password) {
      // В реальном приложении: получить JWT и сохранить его безопасно (cookie, HttpOnly)
      localStorage.setItem("authenticated", "true");
      // навигация на исходную страницу
      navigate(from, { replace: true });
    } else {
      alert("Неверный логин или пароль");
    }
  };

  return (
    

Вход

setUsername(e.target.value)} placeholder="Имя пользователя" /> setPassword(e.target.value)} placeholder="Пароль" />
); }

Примечание: это учебный пример. В продакшне храните токены в безопасных cookie (HttpOnly), используйте HTTPS, CSRF-защиту и проверяйте срок действия токенов на сервере.

Создаём Dashboard

Исходный пример Dashboard из статьи:

        `const Dashboard = () => {  
  return (  
    
      

Welcome to your Dashboard

    
  ); }; export default Dashboard; `

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

Идея: компонент ProtectedRoute

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

import { Navigate, Outlet, useLocation } from "react-router-dom";

export default function ProtectedRoute() {
  const isAuth = localStorage.getItem("authenticated") === "true";
  const location = useLocation();

  if (!isAuth) {
    // Передаём исходный маршрут в состояние, чтобы после логина вернуть пользователя
    return ;
  }

  return ; // рендерит вложенные маршруты
}

В App (или где вы определяете роуты) это будет выглядеть так:

import { BrowserRouter, Routes, Route } from "react-router-dom";
import ProtectedRoute from "./ProtectedRoute";
import Dashboard from "./Dashboard";
import Login from "./Login";
import Home from "./Home";

function AppRoutes() {
  return (
    
      
        } />
        } />
        }>
          } />
        
      
    
  );
}

Таким образом вы централизуете защиту маршрутов и легко расширяете её (роли, права доступа и т. п.).

Перенаправление с помощью Navigate

Компонент Navigate заменил Redirect из v5 и используется декларативно внутри JSX. Пример:

if (!authenticated) {
  return ;
} else {
  return (
    

Welcome to your Dashboard

); }

Параметр replace заменяет текущую запись в истории браузера — полезно, чтобы при нажатии «назад» пользователь не возвращался на страницу, где его выкинули.

Перенаправление с помощью useNavigate()

useNavigate даёт императивный доступ к навигации. Его удобно использовать после обработки событий, например после успешного логина.

import { useNavigate } from "react-router-dom";

const navigate = useNavigate();

// внутри обработчика
navigate("/dashboard");
// или вернуться назад
navigate(-1);

Если вы хотите вернуть пользователя на страницу, с которой он пришёл, передавайте в Navigate состояние (state) и затем используйте location.state.from в Login, как показано в рекомендованном примере выше.

Когда подходы не работают / подводные камни

  • SSR (Next.js): на сервере нет window/localStorage — храните сессионные данные в cookie и проверяйте на сервере.
  • Истечение токена: localStorage не учитывает срок действия токена; проверяйте expiry на клиенте и сервере.
  • Консистентность между вкладками: localStorage не уведомляет React автоматически — можно слушать событие storage и обновлять состояние.
  • XSS-угрозы: хранение JWT в localStorage делает их уязвимыми при XSS. Предпочтительнее — HttpOnly cookies.

Практические рекомендации и чек-лист для реализации

  • Для демо: можно использовать localStorage. Для продакшна — отдавать JWT и хранить в HttpOnly cookie.
  • Сохраняйте маршрут назначения: при редиректе на /login передавайте from в state.
  • Используйте ProtectedRoute/Outlet для декларативной защиты маршрутов.
  • При логине используйте navigate(from, { replace: true }).
  • Обрабатывайте edge-cases: токен просрочен, нет соединения, баги в синхронизации.

Чек-лист ролей:

  • Фронтенд-разработчик: реализовать ProtectedRoute, правильный возврат после логина, обработать replace.
  • Бэкенд-разработчик: корректно выдавать токен, проверять expiry и refresh.
  • QA: тестировать сценарии «вошёл/не вошёл», переход назад, многовкладочный сценарий.

Критерии приёмки

  • Неаутентифицированный пользователь при попытке открыть /dashboard попадает на /login.
  • После успешного входа пользователь возвращается на страницу, с которой пришёл.
  • При нажатии «назад» после логина не происходит возврата на страницу логина (если использован replace).
  • Токены/сессии правильно истекают и пользователь перенаправляется на /login при необходимости.

Короткий словарь

  • Navigate — декларативный компонент для перенаправлений в React Router v6.
  • useNavigate — хук для императивной навигации (функция navigate).
  • ProtectedRoute — паттерн/компонент-обёртка для защиты маршрутов.

Итог

Перенаправления в React Router v6 реализуются двумя паттернами: Navigate для декларативных переходов и useNavigate для императивных. Лучший UX достигается, если сохранять страницу назначения и возвращать пользователя после логина. В продакшне обращайте внимание на безопасность хранения сессий и обработку срока жизни токенов.

Важно: используйте централизованную логику авторизации (Context/Redux) и безопасное хранение токенов.


Примечание: примеры упрощены для обучающих целей.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Как сделать правый клик на Mac
Mac

Как сделать правый клик на Mac

Minecraft VR на Quest 2 и ПК — как запустить
VR игры

Minecraft VR на Quest 2 и ПК — как запустить

Как сделать кроссоверный Ethernet‑кабель
Сети

Как сделать кроссоверный Ethernet‑кабель

Как вести заметки в Notion — практические приёмы
Productivity

Как вести заметки в Notion — практические приёмы

Отключить Popular Highlights на Kindle
Руководство

Отключить Popular Highlights на Kindle

Авторское право на YouTube: что такое strike
Видео

Авторское право на YouTube: что такое strike