В прошлой теме для обращения к ресурсам внутри приложения были использованы маршруты. Теперь добавим к этому приложению навигацию с помощью ссылок. Для этого изменим файл index.html следующим образом:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Маршруты в React</title> </head> <body> <div id="app"></div> <script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script> <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script> <script src="https://unpkg.com/history@5/umd/history.production.min.js" crossorigin></script> <script src="https://unpkg.com/react-router@6.3.0/umd/react-router.production.min.js" crossorigin></script> <script src="https://unpkg.com/react-router-dom@6.3.0/umd/react-router-dom.production.min.js" crossorigin></script> <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> <script type="text/babel"> const Router = ReactRouterDOM.BrowserRouter; const Route = ReactRouterDOM.Route; const Routes = ReactRouterDOM.Routes; const Link = ReactRouterDOM.Link; function Home(){ return <h2>Главная</h2>; } function About(){ return <h2>О сайте</h2>; } function NotFound(){return <h2>Ресурс не найден</h2>; } function Products(){ return <div> <h2>Товары</h2> </div>; } function Nav(){ return <nav> <Link to="/">Главная</Link> <Link to="/about">О сайте</Link> <Link to="/products">Товары</Link> </nav>; } ReactDOM.createRoot( document.getElementById("app") ) .render( <Router> <div> <Nav /> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={ <About />} /> <Route path="/products" element={<Products />} /> <Route path="*" element={<NotFound />} /> </Routes> </div> </Router> ); </script> </body> </html>
Для создания ссылки применяется объект Link, который определен в модуле react-router-dom:
const Link = ReactRouterDOM.Link;
Для определения блока навигации здесь добавлен компонент Nav:
function Nav(){ return <nav> <Link to="/">Главная</Link> <Link to="/about">О сайте</Link> <Link to="/products">Товары</Link> </nav>; }
Для каждой ссылки с помощью атрибута to определяет путь перехода.
Затем компонент Nav помещается в объект Router. И после запуска мы увидим блок ссылок, по которым сможем переходить к ресурсам приложения:
Аналогичный пример с использованием компонентов-классов:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Маршруты в React</title> </head> <body> <div id="app"></div> <script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script> <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script> <script src="https://unpkg.com/history@5/umd/history.production.min.js" crossorigin></script> <script src="https://unpkg.com/react-router@6.3.0/umd/react-router.production.min.js" crossorigin></script> <script src="https://unpkg.com/react-router-dom@6.3.0/umd/react-router-dom.production.min.js" crossorigin></script> <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> <script type="text/babel"> const Router = ReactRouterDOM.BrowserRouter; const Route = ReactRouterDOM.Route; const Routes = ReactRouterDOM.Routes; const Link = ReactRouterDOM.Link; class Home extends React.Component{ render(){ return <h2>Главная</h2>; } } class About extends React.Component{ render(){ return <h2>О сайте</h2>; } } class NotFound extends React.Component{ render(){ return <h2>Ресурс не найден</h2>; } } class Products extends React.Component{ render(){ return <div> <h2>Товары</h2> </div>; } } class Nav extends React.Component{ render(){ return <nav> <Link to="/">Главная</Link> <Link to="/about">О сайте</Link> <Link to="/products">Товары</Link> </nav>; } } ReactDOM.createRoot( document.getElementById("app") ) .render( <Router> <div> <Nav /> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={ <About />} /> <Route path="/products" element={<Products />} /> <Route path="*" element={<NotFound />} /> </Routes> </div> </Router> ); </script> </body> </html>
Кроме объекта Link из модуля react-router-dom для создания ссылок мы можем использовать объект NavLink. Этот объект во многом аналогичен Link за тем исключением, что позволяет использовать состояние ссылки. В частности, с помощью атрибутов className и style можно установить стиль активной ссылки. Так, изменим веб-станицу следующим образом:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Маршруты в React</title> <style> a { margin:5px;} .active{ background-color:#486ca3; color: #fff; padding:6px;} </style> </head> <body> <div id="app"></div> <script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script> <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script> <script src="https://unpkg.com/history@5/umd/history.production.min.js" crossorigin></script> <script src="https://unpkg.com/react-router@6.3.0/umd/react-router.production.min.js" crossorigin></script> <script src="https://unpkg.com/react-router-dom@6.3.0/umd/react-router-dom.production.min.js" crossorigin></script> <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> <script type="text/babel"> const Router = ReactRouterDOM.BrowserRouter; const Route = ReactRouterDOM.Route; const Routes = ReactRouterDOM.Routes; const NavLink = ReactRouterDOM.NavLink; function Home(){ return <h2>Главная</h2>; } function About(){ return <h2>О сайте</h2>; } function NotFound(){return <h2>Ресурс не найден</h2>; } function Products(){ return <div> <h2>Товары</h2> </div>; } function Nav(){ return <nav> <NavLink to="/" className={({ isActive }) =>(isActive ? " active" : "")}>Главная</NavLink> <NavLink to="/about" className={({ isActive }) => (isActive ? " active" : "")}>О сайте</NavLink> <NavLink to="/products" className={({ isActive }) => (isActive ? " active" : "")}>Товары</NavLink> </nav>; } ReactDOM.createRoot( document.getElementById("app") ) .render( <Router> <div> <Nav /> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={ <About />} /> <Route path="/products" element={<Products />} /> <Route path="*" element={<NotFound />} /> </Routes> </div> </Router> ); </script> </body> </html>
Для стилизации активной ссылки в стилях страницы определен класс active
.
Атрибут className
устанавливает этот класс:
className={({ isActive }) =>(isActive ? " active" : "")}
В качестве значения атрибут получает функцию, которая в качестве параметра получает объект со свойством isActive
. Если данная ссылка
представляет текущий путь, то это свойство равно true
. Соответственно мы можем проверить значение этого свойства и в зависимости
от результатов проверки установить или убрать класс active
для ссылки: isActive ? " active" : ""
Обратимся к приложению, и теперь активная ссылка будет стилизована:
Естественно в данном случае, чтобы не повторяться, мы можем вынести установки класса во внешнюю функцию:
const setActive = ({ isActive }) =>(isActive ? " active" : ""); function Nav(){ return <nav> <NavLink to="/" className={setActive}>Главная</NavLink> <NavLink to="/about" className={setActive}>О сайте</NavLink> <NavLink to="/products" className={setActive}>Товары</NavLink> </nav>; }
Также вместо атрибута className для стилизации активной ссылки можно использовать атрибут style, который работает аналогичным образом:
<NavLink to="/" style={({ isActive }) =>({color: isActive ? 'green' : 'blue'})}>Главная</NavLink>
В данном случае опять же атрибут использует функцию, которая в качестве параметра принимает объект со свойством isActive
, если оно равно true
,
то устанавливаем стиль color:green
, иначе ссылка получает синий цвет.