Очень полезные и классные API в React Router v6.
Следующие API помогут вам не только повысить производительность, но и улучшить структуру кода.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
import { BrowserRouter, Routes, Route, Link } from 'react-router-dom'; function App() { return ( <BrowserRouter> <Routes> <Route path="/" element={<Home />} /> <Route path="users/*" element={<Users />} /> </Routes> </BrowserRouter> ); } function Users() { /* All <Route path> and <Link to> values in this component will automatically be "mounted" at the /users URL prefix since the <Users> element is only ever rendered when the URL matches /users/* */ return ( <div> <nav> <Link to="me">My Profile</Link> </nav> <Routes> <Route path="/" element={<UsersIndex />} /> <Route path=":id" element={<UserProfile />} /> <Route path="me" element={<OwnUserProfile />} /> </Routes> </div> ); } |
Выше приведен стандартный код, который используется для создания маршрутов для навигации в проектах React.
Теперь давайте проверим код React router v6:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
import { BrowserRouter, Routes, Route, Link, Outlet } from 'react-router-dom'; function App() { return ( <BrowserRouter> <Routes> <Route path="/" element={<Home />} /> <Route path="users" element={<Users />}> <Route path="/" element={<UsersIndex />} /> <Route path=":id" element={<UserProfile />} /> <Route path="me" element={<OwnUserProfile />} /> </Route> </Routes> </BrowserRouter> ); } function Users() { return ( <div> <nav> <Link to="me">My Profile</Link> </nav> <Outlet /> </div> ); } |
Элемент <Outlet>
используется в качестве заполнителя. В этом случае <Outlet>
позволяет Users
компоненту отображать свои дочерние маршруты. Таким образом, <Outlet>
элемент будет отображать либо a, <UserProfile>
либо <OwnUserProfile>
элемент в зависимости от текущего местоположения.
Таким образом, лучше всего этот элемент можно использовать в макетах. Вы можете просто создать несколько макетов, например, макет панели инструментов (для страницы профиля и участников) или основной макет (для входа и выхода, в основном, когда пользователь не вошел в систему). Наконец, вы можете просто внедрить любой компонент, который вам нужен, в зависимости от его маршрута, а не оборачивать каждый компонент маршрута в родительский компонент макета, например:
1 2 3 4 5 6 7 |
<Route path="/" element={<DashboardLayout />}> <Route path="/" element={<HomePage />} /> <Route path=":id" element={<UserProfile />} / > <Route path="me" element={<OwnUserProfile />} /> </Route> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
import { BrowserRouter, Link, Outlet, useRoutes } from 'react-router-dom'; function App() { // The <BrowserRouter> element is removed from App because the // useRoutes hook needs to be in the context of a <BrowserRouter> // element. // Ex: <BrowserRouter><App /></BrowserRouter>.This is a common // pattern with React Router apps that // are rendered in different environments. To render an <App>, // you'll need to wrap it in your own <BrowserRouter> element. let element = useRoutes([ // A route object has the same properties as a <Route> // element. The `children` is just an array of child routes. { path: '/', element: <Home /> }, { path: 'users', element: <Users />, children: [ { path: '/', element: <UsersIndex /> }, { path: ':id', element: <UserProfile /> }, { path: 'me', element: <OwnUserProfile /> }, ] } ]); return element; } function Users() { return ( <div> <nav> <Link to="me">My Profile</Link> </nav> <Outlet /> </div> ); } |
В React Router v6 есть хорошие API для маршрутизации, который использует простые объекты JavaScript для объявления ваших маршрутов. На самом деле, если вы посмотрите на источник<Routes>
, вы увидите, что на самом деле это всего лишь крошечная оболочка вокруг хука, лежащего в основе алгоритма сопоставления маршрутизатора: useRoutes
.
useRoutes
Хук — это первоклассный API для маршрутизации, который позволяет вам объявлять и составлять маршруты, используя объекты JavaScript вместо элементов React. Продолжая пример выше, давайте посмотрим, как это выглядит с useRoutes
.
Хук принимает ( useRoutes
возможно, вложенный) массив объектов JavaScript, которые представляют доступные маршруты в вашем приложении. У каждого маршрута есть path
, element
и (необязательно) children
, которые представляют собой еще один массив маршрутов.
Этот вложенный массив объектов Javascript сохраняет код СУХИМ и улучшает читабельность кода.
Конфигурация маршрута на основе объектов может показаться вам знакомой, если вы использовали react-router-config
пакет в v5. В версии 6 этот формат конфигурации был повышен до первоклассного API в ядре, и react-router-config
пакет будет объявлен устаревшим.
При этом пример оформления в разделе Outlet можно упростить следующим образом:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
let element = useRoutes([ { path: '/', element: <DashboardLayout/>, children: [ { path: '/', element: <HomePage/> }, { path: ':id', element: <UserProfile /> }, { path: 'me', element: <OwnUserProfile /> }, ] } ]); |
Переадресация ссылок — классная техника для автоматической передачи ссылки через компонент одному из его дочерних элементов. Он дает дочернему компоненту ссылку на элемент DOM, созданный его родительским компонентом. Это позволяет дочернему элементу читать и изменять этот элемент везде, где он используется.
Прежде чем я покажу вам, как «пересылать» ссылки, давайте сначала узнаем, что они из себя представляют и как их создавать.
Чтобы создать ссылку, используйте функцию React с именем React.createRef()
. Затем эти ссылки можно прикрепить к элементам React с помощью атрибута ref. Ссылки чем-то похожи на состояние. При назначении ссылок на свойства экземпляра этого компонента мы можем гарантировать, что на них можно будет ссылаться в любом месте компонента. Проверьте пример ниже:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class MyComponent extends React.Component { constructor(props) { super(props); this.newRef = React.createRef(); //newRef is now available for use throughout our component } ... } class MyComponent extends React.Component { ... render() { return <div ref={this.myRef} />; } } |
Создали ссылку с именем newRef and
и прикрепил ее к элементу div в MyComponent
компоненте. В результате теперь у нас есть возможность обновлять div без изменения состояния.
В этом заключается важность использования ссылок, поскольку вы можете обновлять и изменять элементы без использования переменных состояния, которые приводят к повторному рендерингу компонентов.
Несколько важных моментов прямо из документации :
React.createRef()
получает базовый элемент DOM в качестве своего current
свойства .current
реквизитов, состояния и методов компонента.Как видно из официальной документации React , есть несколько хороших вариантов использования refs:
Давайте представим, что у вас есть компонент ввода. В некоторых частях вашего приложения вы можете захотеть, чтобы курсор сфокусировался на нем, когда пользователь нажимает кнопку. Имеет больше смысла изменять только этот конкретный экземпляр входного компонента без изменения состояния (через refs), а не изменять состояние (через props ), что приведет к повторному рендерингу компонента каждый раз. Точно так же вы можете использовать ссылки для управления состоянием музыкальных или видеоплееров (пауза, воспроизведение, остановка) без их повторного рендеринга каждый раз, когда вы нажимаете кнопку (изменение состояния).
Подумайте о средней кнопке хлопка. Быстрым способом реализации аналогичной функции было бы увеличение значения счетчика, хранящегося в состоянии, каждый раз, когда пользователь щелкает хлопком. Однако это может быть не очень эффективно. Каждый раз, когда пользователь нажимает кнопку хлопка, он будет повторно отображаться, и если вы отправляете сетевой запрос для сохранения значения на сервере, он будет отправлен столько раз, сколько будет нажата кнопка. С помощью refs вы можете ориентироваться на этот конкретный узел и увеличивать его каждый раз, когда пользователь нажимает кнопку, не вызывая повторной визуализации, и, наконец, вы можете отправить один запрос на наш сервер с окончательным значением.
Вы можете использовать ссылки для запуска анимации между элементами, которые зависят от самих себя в своем следующем состоянии, но существуют в разных компонентах (эта концепция называется пересылкой ссылок ). Рефы также можно использовать для упрощения интеграции со сторонними библиотеками DOM, управления многошаговыми состояниями значений формы и т. д.
Теперь перейдем к технике переадресации рефов:
Переадресация ссылок — это метод, который автоматически передает ссылку через компонент одному из его дочерних элементов. Пересылка ссылок очень полезна при создании повторно используемых библиотек компонентов. forwardRef
это функция, используемая для передачи ссылки дочернему компоненту. Давайте рассмотрим пример ниже:
1 2 3 4 5 6 7 8 9 |
function SampleButton(props) { return ( <button className="button"> {props.children} </button> ); } |
Компонент SampleButton()представляет собой модифицированную кнопку, которая будет использоваться во всем приложении аналогично обычной кнопке DOM, поэтому доступ к ее узлу DOM может быть неизбежен для управления фокусом, выбором или связанной с ним анимацией. В приведенном ниже примере SampleComponent()использует React.forwardRefдля получения переданной ему ссылки, а затем перенаправляет ее на кнопку DOM, которую он отображает:
1 2 3 4 5 6 7 8 9 |
const SampleButton = React.forwardRef((props, ref) => ( <button ref={ref} className="button"> {props.children} </button> )); const ref = React.createRef(); <SampleButton ref={ref}>Click me!</SampleButton>; |
Теперь, когда мы обернули SampleButton
компонент с помощью forwardRef
метода, компоненты, использующие его, могут получить ссылку на базовый DOM-узел кнопки и при необходимости получить к нему доступ — точно так же, как если бы они использовали кнопку DOM напрямую.
Вот пояснение к приведенному выше коду:
<button ref={ref}>
, указав ее как атрибут JSX.ref.current
она будет указывать на <button>
узел DOM.Мы рассмотрели только основы, но не все возможности React!🔥 Пробуйте и добавляйте свои наработки.
Источник статьи: https://medium.com/