Підручник з React Router - Як візуалізувати, перенаправляти, переключати, посилати тощо на прикладах коду

Якщо ви тільки-но розпочали роботу з React, ви, мабуть, все ще обгортаєте всю концепцію програми Single Page Application.

Традиційно маршрутизація працює так: припустимо, ви вводите /contactURL-адресу. Браузер зробить запит GET на сервер, а сервер поверне HTML-сторінку як відповідь.

Але, з новою парадигмою програми для односторінкової сторінки, усі запити URL-адрес обслуговуються за допомогою коду на стороні клієнта.

Застосовуючи це в контексті React, кожна сторінка буде компонентом React. React-Router відповідає URL-адресі та завантажує компонент для цієї сторінки.

Все відбувається настільки швидко і безперешкодно, що користувач отримує власний додаток у браузері. Немає кричущої порожньої сторінки між переходами маршруту.

У цій статті ви дізнаєтесь, як використовувати React-Router та його компоненти для створення додатка для однієї сторінки. Тож відкрийте свій улюблений текстовий редактор, і давайте почнемо.

Налаштуйте проект

Створіть новий проект React, виконавши наступну команду.

yarn create react-app react-router-demo

Я буду використовувати пряжу для встановлення залежностей, але ви також можете використовувати npm.

Далі, давайте встановимо react-router-dom.

yarn add react-router-dom

Для стилізації компонентів я буду використовувати фреймворк Bulma CSS. Тож додамо і це.

yarn add bulma

Далі імпортуйте bulma.min.cssу index.jsфайл та очистіть весь шаблонний шаблон із App.jsфайлу.

import "bulma/css/bulma.min.css";

Тепер, коли ви налаштували проект, давайте почнемо зі створення декількох компонентів сторінки.

Створення компонентів сторінки

Створіть каталог сторінок всередині папки src, де ми будемо паркувати всі компоненти сторінки.

Для цієї демонстрації створіть три сторінки - Домашня сторінка, Про мене та Профіль.

Вставте наступне всередину компонентів «Домашня сторінка» та «Про програму».

// pages/Home.js import React from "react"; const Home = () => ( 

This is the Home Page

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras gravida, risus at dapibus aliquet, elit quam scelerisque tortor, nec accumsan eros nulla interdum justo. Pellentesque dignissim, sapien et congue rutrum, lorem tortor dapibus turpis, sit amet vestibulum eros mi et odio.

); export default Home;
// pages/About.js import React from "react"; const About = () => ( 

This is the About Page

Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Duis consequat nulla ac ex consequat, in efficitur arcu congue. Nam fermentum commodo egestas.

); export default About;

Далі в статті ми створимо сторінку профілю.

Створіть компонент Navbar

Почнемо із створення навігаційної панелі для нашого додатка. Цей компонент використовуватиме компонент із react-router-dom.

Створіть каталог з назвою "компоненти" всередині папки src.

// components/Navbar.js import React, { useState } from "react"; import { NavLink } from "react-router-dom"; const Navbar = () => { const [isOpen, setOpen] = useState(false); return ( {/* ... */} ); }; export default Navbar;

isOpenМінлива стану буде використовуватися , щоб викликати меню на мобільних або планшетних пристроїв.

Тож давайте додамо меню гамбургерів.

const Navbar = () => { const [isOpen, setOpen] = useState(false); return ( setOpen(!isOpen)} > {/* ... */} ); };

Щоб додати посилання в меню, використовуйте компонент за react-router-dom.

NavLinkКомпонент забезпечує декларативний спосіб переміщення навколо програми. Він схожий на Linkкомпонент, за винятком того, що він може застосувати активний стиль до посилання, якщо він активний.

Щоб вказати, до якого маршруту рухатись, використовуйте toпроп і передайте назву шляху.

activeClassNameПроп додасть активний клас по посиланню , якщо він в даний момент.

 Home 

У браузері NavLinkкомпонент відображається у вигляді тегу зі hrefзначенням атрибута, яке було передано в toописі.

Також тут потрібно вказати exactпроп, щоб він точно відповідав URL-адресі.

Додайте всі посилання і закінчіть Navbarкомпонент.

import React, { useState } from "react"; import { NavLink } from "react-router-dom"; const Navbar = () => { const [isOpen, setOpen] = useState(false); return ( setOpen(!isOpen)} > Home   About   Profile Log in ); }; export default Navbar; 

Якщо ви помітили тут, я додав кнопку Вхід. Ми повернемось до Navbarкомпонента ще раз, коли обговоримо захищені маршрути пізніше в посібнику.

Візуалізація сторінок

Тепер, коли Navbarкомпонент налаштований, давайте додамо це на сторінку і почнемо з візуалізації сторінок.

Оскільки панель навігації є загальним компонентом для всіх сторінок, замість того, щоб викликати компонент у кожному компоненті сторінки, буде кращим підходом зробити візуалізацію Navbarв загальному макеті.

// App.js function App() { return ( {/* Render the page here */} ); }

Тепер додайте компоненти сторінки всередину контейнера.

// App.js function App() { return ( ); }

Якщо ви перевірите результати зараз, ви помітите, що на сторінку відображається як компонент "Домашня сторінка", так і "Про". Це тому, що ми ще не додали жодної логіки маршрутизації.

You need to import the BrowserRouter component from React Router to add the ability to route the components. All you need to do is wrap all the page components inside of the BrowserRouter component. This will enable all the page components to have the routing logic. Perfect!

But again, nothing's going to change with the results – you are still going to see both the pages rendered. You need to render the page component only if the URL matches a particular path. That's where the Route component from React Router comes into play.

The Router component has a path prop that accepts the page's path, and the page component should be wrapped with the Router, as shown below.

So let's do the same for the Home component.

The exact prop above tells the Router component to match the path exactly. If you don't add the exact prop on the / path, it will match with all the routes starting with a / including /about.

If you go check out the results now, you'll still see both the components rendered. But, if you go to /about, you'll notice that only the About component gets rendered. You see this behavior because the router keeps matching the URL with the routes even after it had matched a route already.

We need to tell the router to stop matching further once it matches a route. This is done using the Switch component from React Router.

function App() { return ( ); }

There you go! You have successfully configured routing in your React app.

Protected Routes and Redirect

When working on Real-world applications, you will have some routes behind an authentication system. You are going to have routes or pages that can only be accessed by a logged-in user. In this section, you'll learn how to go about implementing such routes.

Please note that I'm not going to create any login form or have any back-end service authenticate the user. In a real application, you wouldn't implement authentication the way demonstrated here.

Let's create the Profile page component that should only be accessed by the authenticated user.

// pages/Profile.js import { useParams } from "react-router-dom"; const Profile = () => { const { name } = useParams(); return ( 

This is the Profile Page

{name}

Lorem ipsum dolor sit amet, consectetur adipiscing elit.{" "} Pellentesque risus mi, tempus quis placerat ut, porta nec nulla. Vestibulum rhoncus ac ex sit amet fringilla. Nullam gravida purus diam, et dictum felis venenatis efficitur. Aenean ac{" "} eleifend lacus, in mollis lectus. Donec sodales, arcu et sollicitudin porttitor, tortor urna tempor ligula, id porttitor mi magna a neque. Donec dui urna, vehicula et sem eget, facilisis sodales sem. ); };

We will grab the user's name from the URL using route parameters.

Add the Profile route into the router.

Currently the profile page can be accessed directly. So to make it an authenticated route, create a Higher-Order component (HOC) to wrap the authentication logic.

const withAuth = (Component) => { const AuthRoute = () => { const isAuth = !!localStorage.getItem("token"); // ... }; return AuthRoute; };

To determine if a user is authenticated or not, grab the authentication token that is stored in the browser when the user logs in. If the user is not authenticated, redirect the user to the Home page. The Redirect component from React Router can be used to redirect the user to another path.

const withAuth = (Component) => { const AuthRoute = () => { const isAuth = !!localStorage.getItem("token"); if (isAuth) { return ; } else { return ; } }; return AuthRoute; };

You can also pass in other user information like name and user ID using props to the wrapped component.

Next, use the withAuth HOC in the Profile component.

import withAuth from "../components/withAuth"; const Profile = () => { // ... } export default withAuth(Profile);

Now, if you try to visit /profile/JohnDoe, you will get redirected to the Home page. That's because the authentication token is not yet set in your browser storage.

Alright, so, let's return to the Navbar component and add the login and logout functionalities. When the user is authenticated, show the Logout button and when the user is not logged in show the Login button.

// components/Navbar.js const Navbar = () => { // ... return ( {/* ... */} {!isAuth ? (  Log in  ) : (  Log out  )} ); } 

When the user clicks on the login button, set a dummy token in the local storage, and redirect the user to the profile page.

But we cannot use the Redirect component in this case – we need to redirect the user programmatically. Sensitive tokens used for authentication are usually stored in cookies for security reasons.

React Router has a withRouter HOC that injects the history object in the props of the component to leverage the History API. It also passes the updated match and location props to the wrapped component.

// components/Navbar.js import { NavLink, withRouter } from "react-router-dom"; const Navbar = ({ history }) => { const isAuth = !!localStorage.getItem("token"); const loginUser = () => { localStorage.setItem("token", "some-login-token"); history.push("/profile/Vijit"); }; const logoutUser = () => { localStorage.removeItem("token"); history.push("/"); }; return ( {/* ... */} ); }; export default withRouter(Navbar);

And voilà! That's it. You have conquered the land of authenticated routes as well.

Check out the live demo here and the complete code in this repo for your reference.

Conclusion

I hope by now you have a fair idea of how client-side routing works in general and how to implement routing in React using the React Router library.

In this guide, you learned about the vital components in React Router like Route, withRouter, Link, and so on, along with some advanced concepts like authenticated routes, that are required to build an application.

Do check out the React Router docs to get a more detailed overview of each of the components.