React Router предоставляет мощные инструменты для управления навигацией и маршрутизацией в приложениях на React, но ключевым аспектом является синхронизация маршрутов с состоянием компонентов. Этот процесс позволяет динамически изменять отображение интерфейса на основе текущих параметров маршрута, состояния приложения или пользовательского ввода.
useLocation и useNavigateuseLocation возвращает объект, содержащий информацию о
текущем URL, включая pathname, search и
hash. Этот объект можно использовать для
отслеживания изменений маршрута и синхронизации с локальным
состоянием компонента:
import { useLocation } from 'react-router-dom';
import { useEffect, useState } from 'react';
function SearchPage() {
const location = useLocation();
const [query, setQuery] = useState('');
useEffect(() => {
const params = new URLSearchParams(location.search);
setQuery(params.get('q') || '');
}, [location.search]);
return (
<input
type="text"
value={query}
onCha nge={e => setQuery(e.target.value)}
/>
);
}
В этом примере query всегда соответствует параметру
q в URL, что обеспечивает двустороннюю
синхронизацию состояния и маршрута.
useNavigate позволяет программно менять маршрут и
поддерживать синхронизацию состояния с URL:
import { useNavigate } from 'react-router-dom';
function SearchForm({ query }) {
const navigate = useNavigate();
const handleSubmit = (e) => {
e.preventDefault();
navigate(`/search?q=${encodeURIComponent(query)}`);
};
return (
<form onSub mit={handleSubmit}>
<input type="text" value={query} />
<button type="submit">Поиск</button>
</form>
);
}
useParamsuseParams позволяет получать динамические сегменты
маршрута и использовать их для инициализации и синхронизации
состояния компонента:
import { useParams } from 'react-router-dom';
import { useEffect, useState } from 'react';
function ProductPage() {
const { productId } = useParams();
const [product, setProduct] = useState(null);
useEffect(() => {
fetch(`/api/products/${productId}`)
.then(res => res.json())
.then(data => setProduct(data));
}, [productId]);
if (!product) return <p>Загрузка...</p>;
return <div>{product.name}</div>;
}
Изменение маршрута автоматически вызывает обновление состояния
product, благодаря чему интерфейс остается
синхронизированным с URL.
Link и NavLinkС помощью Link и NavLink можно передавать
состояние маршрута в объекте state, что позволяет
синхронизировать маршрутизацию с внутренним состоянием
компонентов без изменения URL-параметров:
import { Link, useLocation } from 'react-router-dom';
function PostList() {
return (
<ul>
<li>
<Link
to="/post/1"
state={{ fromList: true }}
>
Пост 1
</Link>
</li>
<li>
<Link
to="/post/2"
state={{ fromList: true }}
>
Пост 2
</Link>
</li>
</ul>
);
}
function PostPage() {
const location = useLocation();
const fromList = location.state?.fromList || false;
return <div>{fromList ? 'Перешли со списка постов' : 'Прямой переход'}</div>;
}
Передаваемое состояние позволяет компоненту принимать решения о визуализации на основе контекста навигации, что облегчает управление сложными сценариями пользовательских переходов.
Для сложных интерфейсов часто нужно хранить фильтры, пагинацию или
сортировку в URL. В этом случае сочетание useSearchParams и
useEffect позволяет создавать автоматически
синхронизируемые состояния:
import { useSearchParams } from 'react-router-dom';
import { useState, useEffect } from 'react';
function ProductFilter() {
const [searchParams, setSearchParams] = useSearchParams();
const [category, setCategory] = useState(searchParams.get('category') || '');
useEffect(() => {
setCategory(searchParams.get('category') || '');
}, [searchParams]);
const handleChange = (e) => {
const value = e.target.value;
setCategory(value);
setSearchParams({ category: value });
};
return (
<sel ect value={category} onCha nge={handleChange}>
<option value="">Все категории</option>
<option value="electronics">Электроника</option>
<option value="books">Книги</option>
</select>
);
}
Такой подход гарантирует, что URL и состояние компонента всегда совпадают, что улучшает UX и позволяет сохранять состояние между перезагрузками страницы или копированием ссылки.
Состояние маршрута может использоваться для условного отображения компонентов без изменения маршрута. Это особенно полезно для модальных окон или всплывающих панелей:
import { Routes, Route, useLocation } fr om 'react-router-dom';
function App() {
const location = useLocation();
const background = location.state?.background;
return (
<>
<Routes location={background || location}>
<Route path="/" element={<Home />} />
<Route path="/gallery" element={<Gallery />} />
</Routes>
{background && (
<Routes>
<Route path="/gallery/:id" element={<Modal />} />
</Routes>
)}
</>
);
}
Такое решение позволяет отделить модальные представления от основного маршрута, сохраняя синхронизацию состояния с историей браузера.
useLocation, useParams,
useSearchParams для отслеживания изменений маршрута.useNavigate или setSearchParams для обновления
маршрута при изменении состояния.state в Link и
NavLink.Соблюдение этих принципов обеспечивает гибкую и надежную синхронизацию состояния компонентов с маршрутизацией, что является основой для построения сложных, динамических приложений на React.