Routes. The Beginning

What is the difference between Root and Route and Rout? : Root :

1

) Part of the plant that keeps it firmly in the soil and absorbs water and food from the soil

This is a plant with long roots.

2

3

) Source or basis

The root of the problem is lack of trust.

Money is often said to be the root of all evil.

Root :

1

) Send down roots and begin to grow

This type of plant roots easily.

2

) Plant something

Root the cuttings in peat.

3

) Cause someone to stand fixed and unmoving

He stood rooted to the spot.

Fear rooted him to the spot.

4

) Establish something deeply and firmly

Her love for me is deeply rooted.

This is a story firmly rooted in reality.

Route :

1

) Way taken or planned to get from one place to another

We drove home by a roundabout route.

Route :

1

) Send something by a specified route

This flight is routed to Kolkata via Patna.

Rout :

1

) Utter defeat ending in disaster

After our fourth goal, the match became a rout.

The terrified army fled in rout.

Rout :

1

) Defeat someone completely

Make someone retreat in confusion

The Prime Minister resigned after his party was routed in the election.

What is the difference between Root and Route and Rout? To HOME PAGE

It used to be that routes.rb had a root route line. But I don’t see it anymore even though when I run the server I see the «Yay! You’re on Rails!» page. I can’t find where it is defined so I can override it!

asked Feb 7, 2020 at 19:55

pitosalas's user avatar

On a new project it doesn’t use a root route, it just renders the rails’ default new project page.

Just add the line:

root to: 'somecontroller#someaction'

and you are done.

answered Feb 7, 2020 at 20:16

arieljuod's user avatar

2 gold badges25 silver badges36 bronze badges

The routes.rb file is in the config/ directory of your rails project. You can define a root route there and direct it using the routes DSL

answered Feb 7, 2020 at 20:19

Steven Foster's user avatar

Above answers are correct but incomplete.

With Rails 6 it seems that there’s no explicit root route (‘/’). Instead the rails gem(s) handle it by displaying the standard «Yay you’re on Rails» page (see railsties/templates/welcome/index.html.erb). It’s a fixed page, bypassing routes.rb and layouts etc.

This behavior seems to only happen in development mode and when you haven’t actually defined a root route.

So it seems that the page is fixed and unmodifiable. But it can easily be replaced by a root route.

answered Feb 7, 2020 at 21:57

pitosalas's user avatar

12 gold badges71 silver badges118 bronze badges

When setting up the root route, is there any compelling reason to choose this syntax:

map.root :controller => "login", :action => 'show'

over this syntax:

match "/" => "login#show"

The second syntax will allow you to use the :constraints option, where the first wont. Is there any reason to use the first option?

asked Mar 1, 2011 at 3:17

SooDesuNe's user avatar

answered Mar 1, 2011 at 4:15

Braden Becker's user avatar

root :to => "Something#index"

The methods you suggested sound like they may cause conflicts later on down the road.

answered Mar 1, 2011 at 3:31

providence's user avatar

13 gold badges46 silver badges62 bronze badges

In Rails 4, here’s a quicker code you can use:

 root 'login#new_session'

You can substitute new_session with show/index/etc, just make sure to define it in your login controller.

answered Aug 10, 2013 at 18:24

Ben K.'s user avatar

root :to => 'login#show'
match '/' => 'login#show', :as => :root

Just like other paths, if you want a root_path, then for the match '/', you have to specify it by yourself.

So I think they just do the same thing (routing you to login#show if the path is /), but the first one would have more semantic meaning.

answered Mar 1, 2011 at 4:26

PeterWong's user avatar

9 gold badges59 silver badges68 bronze badges

To make our Angular application modular, it is best to assign the routes module-wise. Therefore, we will take how we can create root routes and child routes in this angular routing and sub routing example.

To navigate to different pages in your application, you also want the application to be a SPA (Single Page Application), with no page reloading. Your app needs routing, and angular makes it very easy. Routing means navigating between the pages. You have seen many websites with links that direct you to the new page. This can be achieved using routing.

We also see the sub routing or children routing for our components. That means, in our application, there is one root route, and other routes are for their respective components.

Now, the first thing is to create an Angular project.

Install the Angular 12 Project

ng new angroute

Remember, you need to add the app routing by saying yes to the prompt when creating a new project. Here I have allowed add Angular routing.

Now, install the bootstrap CSS framework.

npm install bootstrap --save

Add the Bootstrap file inside the angular.json file.

"styles": [ "src/styles.css", "./node_modules/bootstrap/dist/css/bootstrap.min.css"
],
ng g c header --spec=false
<!-- header.component.html -->
<nav class="navbar navbar-expand-lg navbar-light" style="background-color: #e3f2fd;"> <a class="navbar-brand brand-custom" data-hren="#">Angular 12 Routing Example</a> <div class="collapse navbar-collapse" id="navbarText"> <ul class="navbar-nav ml-auto"> <li class="nav-item"> <a class="nav-link login-custom" data-hren="#">Students <span class="sr-only">(current)</span></a> </li> <li class="nav-item"> <a class="nav-link register-custom" data-hren="#">Home</a> </li> </ul> </div>
</nav>
<!-- app.component.html -->
<div> <app-header></app-header>
</div>

Save the file and start the angular development server.

ng serve --open

You will see the navigation bar with three nav items.

So here, one item is Home, and one is Students.

That means our application has one root route for Home, and others are sub-routes like for students module.

When creating the project, we have created one routing module called app-routing.module.ts. So we will define the Root routes inside that file.

Add Root Routes

ng g c home --spec=false

Now, add that component inside the app-routing.module.ts file.

// app-routing.component.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HomeComponent } from './home/home.component';
const routes: Routes = [ { path: 'home', component: HomeComponent }
];
@NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule]
})
export class AppRoutingModule { }

So, here we have defined the root routes for our angular application. Now add the router-outlet inside the app.component.html file to display the content of the home component.

<!-- app.component.html -->
<div> <app-header></app-header> <div class="container"> <router-outlet></router-outlet> </div>
</div>

Also, add the navigation link inside the header.component.html file.

<!-- header.component.html -->
<li class="nav-item"> <a class="nav-link register-custom" routerLink="/home">Home</a>
</li>

Save the file and go to the browser and click the Home link. You can see that we can see the content of the home.component.html file. So, we have taken care of the Root routes. Now, it is time to create a student module and define the student module’s sub-routes.

Дополнительно:  Отключение PowerShell и прочие особенности борьбы с Malware. Часть I / Хабр

Create a student module and components.

ng g module student

So, it will create a folder inside the app folder called the student, and inside that folder, it will create a student.module.ts file.

The next step is to create the three angular components related to the student module. So let us do that.

ng g c student/student --spec=false
ng g c student/student-list --spec=false
ng g c student/student-detail --spec=false

It will create the three folders inside the src >> app >> student folder.

Now, all these four components are already imported inside the student.module.ts file.

// student.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { StudentComponent } from './student/student.component';
import { StudentListComponent } from './student-list/student-list.component';
import { StudentDetailComponent } from './student-detail/student-detail.component';
@NgModule({ declarations: [StudentComponent, StudentListComponent, StudentDetailComponent], imports: [ CommonModule ]
})
export class StudentModule { }

We do not need to import all these components inside the app.module.ts file.

Instead, we need to import this student.module.ts file inside the app.module.ts file.

// app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { StudentModule } from './student/student.module';
import { AppComponent } from './app.component';
import { HeaderComponent } from './header/header.component';
import { HomeComponent } from './home/home.component';
@NgModule({ declarations: [ AppComponent, HeaderComponent, HomeComponent ], imports: [ BrowserModule, AppRoutingModule, StudentModule ], providers: [], bootstrap: [AppComponent]
})
export class AppModule { }

So, all of our student components are registered to the angular application.

Create a Student route.

// student-routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { StudentComponent } from './student/student.component';
import { StudentListComponent } from './student-list/student-list.component';
import { StudentDetailComponent } from './student-detail/student-detail.component';
const routes: Routes = [ { path: 'student', component: StudentComponent, children: [ { path: 'list', component: StudentListComponent }, { path: 'detail', component: StudentDetailComponent } ] }
];
@NgModule({ imports: [RouterModule.forChild(routes)], exports: [RouterModule]
})
export class StudentRoutingModule { }

So, here we have defined the sub-routing for the student module. The main path is a  /student and its children are /student/list and /student/detail.

So that means we have defined the subroutes for the student module. The only remaining thing is to register this routing module to the student.module.ts file.

Remember, both student.module.ts and student-routing.module.ts files are different. You can see this structure as same as our root angular project structure like app.module.ts and app-routing.module.ts.

// student.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { StudentRoutingModule } from './student-routing.module';
import { StudentComponent } from './student/student.component';
import { StudentListComponent } from './student-list/student-list.component';
import { StudentDetailComponent } from './student-detail/student-detail.component';
@NgModule({ declarations: [StudentComponent, StudentListComponent, StudentDetailComponent], imports: [ CommonModule, StudentRoutingModule ]
})
export class StudentModule { }
<!-- student.component.html -->
<div class="container"> <router-outlet></router-outlet>
</div>

This router-outlet will only show the component related to the student module. So it is different from the root routing’s router-outlet, which is still in the place inside the app.component.html file.

Also, now add the router link inside the header.component.html file.

<!-- header.component.html -->
<nav class="navbar navbar-expand-lg navbar-light" style="background-color: #e3f2fd;"> <a class="navbar-brand brand-custom" data-hren="#">Angular 12 Routing Example</a> <div class="collapse navbar-collapse" id="navbarText"> <ul class="navbar-nav ml-auto"> <li class="nav-item"> <a class="nav-link login-custom" routerLink="/student/list">Students <span class="sr-only">(current)</span></a> </li> <li class="nav-item"> <a class="nav-link register-custom" routerLink="/home">Home</a> </li> </ul> </div>
</nav>

Save the file to the browser and navigate to the http://localhost:4200/student/list

You can see that it is rendering the correct component. Now, go to the http://localhost:4200/student/detail

It will also show the right component, and now our student module is working.

You can still go to http://localhost:4200/home, and it will render the correct component, which is HomeComponent.

This is how you can organize your project Angular module-wise with the root and children routing.

Summary of Angular Routing

  1. You added the Angular router to navigate among different components.
  2. You turned the AppComponent into a navigation shell with <a> links and a <router-outlet>.
  3. You configured the router in an AppRoutingModule.
  4. You configured the router in the StudentRoutingModule.
  5. You defined simple routes as redirect routes.
  6. You used the routerLink directive in anchor elements.

Finally, the Angular 12 Routing and Sub Routing Example are over. Thanks for taking it.

Время на прочтение

Роуты в рельсах очень важная вещь. Но до поры до времени можно даже не обращать внимание на них. Особенно если вы пользуетесь командой scaffold, которая автоматически все прописывает. Но в какой-то момент появляется необходимость создавать нестандартные роуты. Это значит самое время залезать в файл routes.rb в папке config вашего проекта.

Что такое роуты

Роуты — это система маршрутов (путей, url’ов) на вашем сайте. Благодаря роутам мы можем иметь красивые и ясные для пользователей ссылки. Введя ссылку вроде mysite.ru/articles/2008/november/13 мы получим все статьи за 13 ноября 2008 года, а по ссылке mysite.ru/shop/shoes получим каталог обуви из вашего магазина. При всем при этом, структура каталогов сайта никак не изменяется. В любой момент мы можем изменить роуты не трогая расположение самих файлов. Но чтобы все это работало нам необходимо настроить роуты.

К практике

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

rails routes
cd routes

Окей. Проект создан и мы вошли в рабочую папку. Сразу набросимся на роуты:

эта команда вам выдаст две строчки стандартных роутов.
/:controller/:action/:id
/:controller/:action/:id.:format

Это значит, что любой урл сейчас будет парситься по этим двум правилам.
:controller — это Контроллер =). Это компонент MVC, который чаще всего выступает как посредник между Представлением (HTML) и Моделью (база данных, скажем). Дальше будет яснее, но скорее всего вы итак знаете, что это такое.
:action — это вызываемый метод контроллера. У контроллера обычно много методов.
:id — если я вно не указывать запрет на создание id, то по умолчанию любая модель (таблица БД) создается с полем id. Поэтому любой элемент модели имеет id. И когда вы хотите удалить/редактировать/что угодно делать с каким-то конкретным элементом модели вы обязаны передать в контроллер этот самый id.

Окей. Давайте мы создадим новостной журнал. Для этого нам нужны:
— Таблица news в нашей базе данных (Модель). В БД мы будем хранить заголовок статьи (title), автора статьи (author) и собственно саму статью (article)
— Набор методов для работы с БД (Контроллер)
— HTML формы для ввода, редактирования, чтения новостей (Представление)
Мы можем создавать все это по отдельности. Но сейчас мы упростим себе задачу и используем функцию scaffold для генерации пачки готовых файлов.

./script/generate scaffold Magazine title:string author:string article:text

Мы только что создали все выше перечисленное (а также Helpers, о которых как-нибудь в другой раз). Также команда scaffold сама создала необходимые роуты. Еще раз наберите команду rake routes и вывалится кипа новых роутов

magazines GET /magazines {:controller=>"magazines", :action=>"index"}
formatted_magazines GET /magazines.:format {:controller=>"magazines", :action=>"index"} POST /magazines {:controller=>"magazines", :action=>"create"} POST /magazines.:format {:controller=>"magazines", :action=>"create"}
new_magazine GET /magazines/new {:controller=>"magazines", :action=>"new"}
formatted_new_magazine GET /magazines/new.:format {:controller=>"magazines", :action=>"new"}
edit_magazine GET /magazines/:id/edit {:controller=>"magazines", :action=>"edit"}
formatted_edit_magazine GET /magazines/:id/edit.:format {:controller=>"magazines", :action=>"edit"}
magazine GET /magazines/:id {:controller=>"magazines", :action=>"show"}
formatted_magazine GET /magazines/:id.:format {:controller=>"magazines", :action=>"show"} PUT /magazines/:id {:controller=>"magazines", :action=>"update"} PUT /magazines/:id.:format {:controller=>"magazines", :action=>"update"} DELETE /magazines/:id {:controller=>"magazines", :action=>"destroy"} DELETE /magazines/:id.:format {:controller=>"magazines", :action=>"destroy"}

Теперь мы запустим сервер и поиграемся с журналом. Но сперва мы создадим нашу базу данных и запустим миграции.

Дополнительно:  Не создается дамп памяти windows 10

rake db:create
rake db:migrate
./script/server

Наш журнал теперь доступен по адресу localhost:3000/magazines
Создайте пару новых статей.

Вернемся к таблице роутов выше. Первый столбец — это именные роуты. Они очень удобны. Есть несколько вариантов сейчас сделать ссылку на создание новой статьи. Откройте файл app/views/magazines/index.html.erb — это представление для метода index в контроллере magazines_controller.
В самом низу давайте допишем немного кода.

<hr>
<%= link_to 'Новая статья', :action => 'new' %><br />
<%= link_to 'Новая статья', '/magazines/new' %><br />
<%= link_to 'Новая статья', new_magazine_path %><br />
<%= link_to 'Новая статья', new_magazine_url %><br />

Самым правильным будет использование последних двух методов. Разница в том, что url возвращает полную ссылку (http://localhost:3000/magazines/new), а path только путь (/magazines/new). Почему лучше пользоваться именными роутами? Именной роут это переменная, изменив которую вы меняете все ссылки, которые пользуются этим роутом. Писать пути от руки вобще не рекомендуется, если приспичило, то лучше написать :action => ‘new’ (зачастую именных роутов на все случаи жизне не хватает, поэтому этот вариант очень распространен).

Второй столбец таблицы — это метод запроса. Одна и таже ссылка, но с разным методом ведет на разные методы контроллера. К примеру, в том же app/views/magazines/index.html.erb:
<%= link_to 'Show', magazine %>
<%= link_to 'Destroy', magazine, :method => :delete %>

В первой ссылке исполняется дефолтный GET запрос (можно не указывать в ссылке :method=>:get), а во второй отправляется метод :delete. А ссылка magazine остается в обоих случаях одинаковая.

Третий столюбец — это собственно ссылки, которые мы получим в HTML. Последний столбец — это соответствие ссылок контроллеру и методу. Как уже выше писалось, любую ссылку можно представить в виде пары :controller, :action (ну и иногда :method).

<%= link_to ‘Ссылка на другой контроллер из контроллера magazines’, :controller => ‘blogs’, :action=>’show’, :id=>’1′, :method=>’GET’ %>
Так мы получим ссылку на блог с индексом 1. (Тут метод :get можно было и не указывать)
<%= link_to ‘Ссылка на родной метод контроллера’, :action => ‘show’, :id => ‘1’ %>
Ссылка на статью с индексом 1. Контроллер и HTTP метод в данном случае указывать не надо, так как GET исполняется по умолчанию, а контроллер, если не указан, выполняется тот же.

Тепрь откройте файл config/routes.rb (можете удалить весь закомментированный текст)

map.resources :magazines
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'

Первую строчку вставила команда scaffold. Эта строчка и добавила нам пачку роутов, которую мы наблюдали выше.

Если вы сейчас наберете просто localhost:3000 вы попадете на приветственную страницу. Давайте это исправим.

map.root :controller => 'magazines'

Теперь из папки public удалите index.html и зайдя на localhost:3000 вы попадете напрямую куда надо =). Кроме того если вы просмотрите все роуты занова (rake routes), то увидите новый именной роут root. И в меню сможете сделать ссылку на «Главную» вида:

<%= link_to 'Главная', root %>

И вы всегда без ущерба ссылкам сможете изменить домашнюю страницу, скажем, на ваш магазин map.root :controller => ‘shop’

II уровень

Собственно создав root вы создали первый именной роут своими руками.
Давайте создадим именной роут «localhost:3000/zhurnal». Не хотим мы буржуйский ‘magazines’, хотим ‘zhurnal’!

map.zhurnal '/klevi_zhurnal/:id', :controller => 'magazines', :id => nil

Итак, мы создали именной роут zhurnal, урл которого будет выглядеть как localhost:3000/klevi_zhurnal, а контент он будет получать от контроллера magazines. Если мы попробуем прочесть статью теперь вроде localhost:3000/klevi_zhurnal/1 — то мы обламаемся. Внесем в наш роут немного изменений:

map.zhurnal '/klevi_zhurnal/:action/:id', :controller => 'magazines', :action => 'index', :id => nil

Что все это значит:
— урл вида /klevi_zhurnal/ будет отработан :controller => ‘magazines’, :action => ‘index’, :id => ‘nil’ — то есть мы получим индексовую страницу (index.html.erb)
— /klevi_zhurnal/1 выплюнет ошибку, что action ‘1’ не существует (посмотрите на последовательность передачи аргумента в роуте)
— /klevi_zhurnal/show скажет, что ID не указано
— /klevi_zhurnal/show/1 — выдаст вам статью с ID=1 (если она конечно существует)
— /klevi_zhurnal/edit/1 — выдаст форму редактирования этой статьи

Правда теперь несколько тяжелее выглядят сами ссылки:
Вместо <%= link_to ‘Все статьи’, magazines_path %> будет <%= link_to ‘Все статьи’, zhurnal_path %>
Вместо <%= link_to ‘Статья номер 1’, magazine_path(‘1’) %> будет <%= link_to ‘Статья номер 1′, zhurnal_path(:action=>’show’, :id=>’1′) %>

Обратите внимание на то, что для лучшего понимания роутов введена система множественного/единственного числа:
показать все статьи magazines_path,
показать отдельную статью: magazine_path.
Чорт — не самое правильное слово вообще выбрал =). Если бы у нас все называлось Article:
index => articles_path, show => article_path(:id)

Теперь давайте создадим новый метод.
Откройте app/controllers/magazines_controller.rb
Добавьте туда метод

теперь все работает! =)

На этом вводная часть заканчивается. Дальше нас ждут более изощренные методы извращения ). Но не сегодня.
Спасибо, за потраченное на чтение статьи время ).

API для желающих
Скринкасты Райана Бейтса

Время на прочтение

image

Время чтения

: 10 минут

React Router v4 — это переработанный вариант популярного React дополнения. Зависимые от платформы конфигурации роутов из прошлой версии были удалены и теперь всё является простыми компонентами.

Этот туториал покрывает всё что вам нужно для создания веб-сайтов с React Router. Мы будем создавать сайт для локальной спортивной команды.

Хочешь посмотреть демку?

Установка

React Router v4 был разбит на 3 пакета:

react-router

router-dom

react-router-native

react-router предоставляет базовые функции и компоненты для работы в двух окружениях(Браузере и react-native)

Мы будем создавать сайт который будет отображаться в браузере, поэтому нам следует использовать react-router-dom. react-router-dom экспортирует из react-router все функции поэтому нам нужно установить только react-router-dom.

npm install --save react-router-dom

Router

При старте проекта вам нужно определить какой тип роутера использовать. Для браузерных проектов есть BrowserRouter и HashRouter компоненты. BrowserRouter — следует использовать когда вы обрабатываете на сервере динамические запросы, а HashRouter используйте когда у вас статический веб сайт.

Обычно предпочтительнее использовать BrowserRouter, но если ваш сайт расположен на статическом сервере(от перев. как github pages), то использовать HashRouter это хорошее решение проблемы.
Наш проект предполагает использование бекенда поэтому мы будем использовать BrowserRouter.

История — History

Остальные функции предоставляемые в React Router полагаются на доступность объекта history через context, поэтому они должны рендериться внутри компонента Router.

Заметка: Компоненты React Router не имеющие в качестве предка компонент Router не будут работать, так как не будет доступен context.

Рендеринг Router

Компонент Router ожидает только один элемент в качестве дочернего. Что бы работать в рамках этого условия, удобно создать компонент <App/> который рендерить всё ваше приложение(это так же важно для серверного рендеринга).

import { BrowserRouter } from 'react-router-dom';
ReactDOM.render(( <BrowserRouter> <App /> </BrowserRouter>
), document.getElementById('root'))

App компонент

Наше приложение начинается с <App/> компонента который мы разделим на две части. <Header/> который будет содержать навигационные ссылки и <Main/> который будет содержать контент роутов.

// Этот компонент будет отрендерен с помощью нашего <Router>
const App = () => ( <div> <Header /> <Main /> </div>
)

Routes

<Route/> компонент это главный строительный блок React Router’а. В том случае если вам нужно рендерить элемент в зависимости от pathname URL’ов, то следует использовать компонент <Route/>

Path — путь

<Route /> принимает path в виде prop который описывает определенный путь и сопоставляется с location.pathname. 

<Route path='/roster'/>
<Route path='/roster'/>
// Когда location.pathname это '/', prop path не совпадает
// Когда location.pathname это '/roster' или '/roster/2', prop path совпадает
// Если установлен exact prop. Совпадает только строгое сравнение '/roster', но не
// '/roster/2'
<Route exact path='/roster'/>

Заметка: Когда речь идет о пути React Router думает только о пути без домена. Это значит, что в адресе:

http://www.example.com/my-projects/one?extra=false

React Router будет видеть только /my-projects/one

Сопоставление пути

npm пакет path-to-regexp компилирует prop path в регулярное выражение и сопоставляет его против location.pathname. Строки path имеют более сложные опции форматирования чем объясняются здесь. Вы можете почитать документацию.

Дополнительно:  Почему пищит компьютер при включении 3 раза, не включается? При включении компьютер пищит, не загружается, что делать?

Когда пути сопоставляются создается объект match который содержит свойства:

  • url — сопоставляемая часть текущего location.pathname
  • path — путь в компоненте Route
  • isExact — path в Route === location.pathname
  • params — объект содержит значения из path которые возвращает модуль path-to-regexp

Заметка: Можете поиграться с тестером роутов и посмотреть как создается объект match.

Создание наших роутов

Компонент Route может быть в любом месте в роутере, но иногда нужно определять, что рендерить в одно и тоже место. В таком случае следует использовать компонент группирования Route’ов — <Switch/>. <Switch/> итеративно проходит по дочерним компонентам и рендерит только первый который подходит под location.pathname.

У нашего веб-сайта пути которые мы хотим сопоставлять такие:

  • / — Главная страница
  • /roster — Страница команд
  • /roster/:number — Страница профиля игрока по номеру
  • /schedule — Расписание игр команды

По порядку сопоставления путей в нашем приложении, все что нам нужно сделать это создать компонент Route с prop path который мы хотим сопоставить.

<Switch> <Route exact path='/' component={Home}/> {/* Оба /roster и /roster/:number начинаются с /roster */} <Route path='/roster' component={Roster}/> <Route path='/schedule' component={Schedule}/>
</Switch>

Что делает рендер компонента Route?

У Route есть 3 props’a которые описывают каким образом выполнить рендер сопоставляя prop path с location.pathname и только один из prop должен быть представлен в Route:

  • component — React компонент. Когда роут удовлетворяется сопоставление в path, то он возвращает переданный component (используя функцию React.createElement).
  • render — функция которая должна вернуть элемент React. Будет вызвана когда удовлетворится сопоставление в path. Render довольно похож на component, но используется для inline рендеринга и подстановки необходимых для элемента props[5].
  • children — в отличие от предыдущих двух props children будет всегда отображаться независимо от того сопоставляется ли path или нет.

<Route path='/page' component={Page} />
const extraProps = { color: 'red' }
<Route path='/page' render={(props) => ( <Page {...props} data={extraProps}/>
)}/>
<Route path='/page' children={(props) => ( props.match ? <Page {...props}/> : <EmptyPage {...props}/>
)}/>

В типичных ситуациях следует использовать component или render. Children prop может быть использован, но лучше ничего не делать если path не совпадает с location.pathname.

Main

Сейчас мы опишем основную структуру роутера. Нам просто нужно отобразить наши маршруты. Для нашего приложения мы будем использовать компонент <Switch/> и компонент <Route/> внутри нашего компонента <Main/> который поместит сгенерированный HTML удовлетворяющий сопоставлению path внутри.

<Main/> DOM узла(node)

import { Switch, Route } from 'react-router-dom'
const Main = () => ( <main> <Switch> <Route exact path='/' component={Home}/> <Route path='/roster' component={Roster}/> <Route path='/schedule' component={Schedule}/> </Switch> </main>
)

Заметка: Route для главной страницы содержит prop exact, благодаря которому пути сравниваются строго.

Унаследованные роуты

Профиль игрока /roster/:number не включен в <Switch/>. Вместо этого он будет рендериться компонентом <Roster/> который рендериться всякий раз когда путь начинается с /roster.

В компоненте Roster мы создадим компоненты для двух путей:

  • /roster — с prop exact
  • /roster/:number — этот route использует параметр пути, который будет отловлен после /roster

const Roster = () => ( <Switch> <Route exact path='/roster' component={FullRoster}/> <Route path='/roster/:number' component={Player}/> </Switch>
)

Может быть полезным группирование роутов которые имеют общие компоненты, что позволяет упростить родительские маршруты и позволяет отображать контент который относиться к нескольким роутам.

К примеру <Roster/> может быть отрендерен с заголовком который будет отображаться во всех роутах которые начинаются с /roster.

const Roster = () => ( <div> <h2>This is a roster page!</h2> <Switch> <Route exact path='/roster' component={FullRoster}/> <Route path='/roster/:number' component={Player}/> </Switch> </div>
)

Параметры в path

Иногда нам требуется использовать переменные для получения какой либо информации. К примеру, роут профиля игрока, где нам требуется получить номер игрока. Мы сделали это добавив параметр в prop path.

:number часть строки в /roster/:number означает, что часть path после /roster/ будет получена в виде переменной и сохранится в match.params.number. К примеру путь /roster/6 сгенерирует следующий объект с параметрами:

{ number: '6' // Любое переданное значение интерпретируется как строка}

Компонент <Player/> будет использовать props.match.params для получения нужной информации которую следует отрендерить.

// API возращает информацию об игроке в виде объекта
import PlayerAPI from './PlayerAPI'
const Player = (props) => { const player = PlayerAPI.get( parseInt(props.match.params.number, 10) ) if (!player) { return <div>Sorry, but the player was not found</div> } return ( <div> <h1>{player.name} (#{player.number})</h1> <h2>{player.position}</h2> </div>
)

Заметка: Вы можете больше изучить о параметрах в путях в пакете path-to-regexp

Наряду с компонентом <Player/> наш веб-сайт использует и другие как <FullRoster/>, <Schedule/> и <Home/>.

const FullRoster = () => ( <div> <ul> { PlayerAPI.all().map(p => ( <li key={p.number}> <Link to={`/roster/${p.number}`}>{p.name}</Link> </li> )) } </ul> </div>
)
const Schedule = () => ( <div> <ul> <li>6/5 @ Спартак</li> <li>6/8 vs Зенит</li> <li>6/14 @ Рубин</li> </ul> </div>
)
const Home = () => ( <div> <h1>Добро пожаловать на наш сайт!</h1> </div>
)

Ссылки

Последний штрих, наш сайт нуждается в навигации между страницами. Если мы создадим обычные ссылки то страница будет перезагружаться. React Router решает эту проблему компонентом <Link/> который предотвращает перезагрузку. Когда мы кликаем на <Link/> он обновляет URL и React Router рендерит нужный компонент без обновления страницы.

import { Link } from 'react-router-dom'
const Header = () => ( <header> <nav> <ul> <li><Link to='/'>Home</Link></li> <li><Link to='/roster'>Roster</Link></li> <li><Link to='/schedule'>Schedule</Link></li> </ul> </nav> </header>
)

<Link/> использует prop to для описания URL куда следует перейти. Prop to может быть строкой или location объектом (который состоит из pathname, search, hash, state свойств). Если это строка то она конвертируется в location объект.

<Link to={{ pathname: '/roster/7' }}>Player #7</Link>

Работающий пример

Весь код нашего веб сайта доступен по этому адресу на codepen.

Route готов!

Надеюсь теперь вы готовы погрузиться в изучение деталей маршрутизации веб приложений.

Мы использовали самые основные компоненты которые вам понадобятся при создании собственных веб приложений (<BrowserRouter.>, <Route.>, and <Link.>), но есть еще несколько компонентов и props которые здесь не рассмотрены. К счастью у React Router есть прекрасная документация где вы можете найти более подробное объяснение компонентов и props. Так же в документации предоставляются работающие примеры с исходным кодом.

Пояснения

// стандартный location
{ pathname: '/', search: '', hash: '', key: 'abc123' state: {} }
<Route path='/one' component={One}/>
// React.createElement(props.component)
<Route path='/two' render={() => <Two />}/>
// props.render()

Оцените статью
Master Hi-technology