# Программируем переходы

*ОБНОВЛЕНИЕ 2018: в учебнике хорошая теория, но ему уже два года. Проверяйте версии пакетов. За выходом нового учебника можно следить в* [*telegram канале*](http://bit.ly/2FI9nhs) *или* [*twitter*](http://bit.ly/2FU6zRL)

*На* [*канале*](http://bit.ly/2FI9nhs) *так же проводятся бесплатные вебинары, публикуются переводы и авторские материалы,* [*присоединяйтесь*](http://bit.ly/2FI9nhs)*!*

## Программируем переходы

*(конечно, дело касается "переходов по ссылкам")*

Давайте рассмотрим очень "выдуманный пример":

На главной странице у нас есть форма, в которой мы можем написать любой жанр. По кнопке - перейти - мы попадаем по адресу:

`http://localhost:3000/genre/жанр_из_формы/`

Динамический роут `/genre/:genre` - как раз позволит нам это.

Практической пользы в этом никакой, но так мы рассмотрим переходы "программно" на деле.

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

Приступим:

*src/components/Home/index.js*

```javascript
import React, { Component } from 'react'
import { browserHistory } from 'react-router'

export default class Home extends Component {
  handleSubmit(e) {
    e.preventDefault()
    const value = e.target.elements[0].value.toLowerCase()
    browserHistory.push(`/genre/${value}`)
  }
  render() {
    return (
      <div className='row'>
        <div className='col-md-12'>Раздел /</div>
        <form className='col-md-4' onSubmit={this.handleSubmit}>
          <input type='text' placeholder='genreName'/>
          <button type='submit'>Перейти</button>
        </form>
      </div>
    )
  }
}
```

Все предельно прозрачно: мы использовали *browserHistory* **API**, просто "[пушнув](https://developer.mozilla.org/ru/docs/Web/API/History_API)" (*pushState*) новую запись в историю.

**Замечание:** *browserHistory из react-router, использует библиотеку* [*history*](https://github.com/mjackson/history)*, которая в свою очередь использует* [*возможности современных браузеров*](https://developer.mozilla.org/ru/docs/Web/API/History_API)*.*

Если мы передадим значение rock - по клику на кнопку нас "перебросит" на:

`http://localhost:3000/genre/rock`

Вопрос валидации здесь не важен, так как цель данного урока не в этом.

Важно отметить, что если вы передадите историю в роутер, **отличную** от того, что используется здесь - приложение сломается. Честно говоря, на практике я не встречался с такой проблемой, но мне нравится ее решение, которое приводится в [официальной документации](https://github.com/reactjs/react-router-tutorial/tree/master/lessons/12-navigating) (*ES5 синтаксис*).

### Использование this.context для программной навигации

*src/components/Home/index.js*

```javascript
import React, { Component, PropTypes } from 'react'

export default class Home extends Component {
  constructor() {
    super();
    this.handleSubmit = this.handleSubmit.bind(this)
  }
  handleSubmit(e) {
    e.preventDefault()
    const value = e.target.elements[0].value.toLowerCase()
    this.context.router.push(`/genre/${value}`)
  }
  render() {
    return (
      <div className='row'>
        <div className='col-md-12'>Раздел /</div>
        <form className='col-md-4' onSubmit={this.handleSubmit}>
          <input type='text' placeholder='genreName'/>
          <button type='submit'>Перейти</button>
        </form>
      </div>
    )
  }
}

Home.contextTypes = {
  router: PropTypes.object.isRequired
}
```

Так как, в будущем мы еще столкнемся с использованием **this.context.router** и так как этот вариант является пуленепробиваемым - давайте оставим его.

У меня есть парочка вопросов на знание экосистемы react'a.

1. Зачем используется `this.handleSubmit = this.handleSubmit.bind(this)` ?
2. Будет ли работать `this.context.router.push` если убрать последние три строки (там где проверяются props) ?

**Ответы:**

1. React с версии 0.14 (предыдущей, перед 15.0) не использует автобиндинг если используются ES2015 классы. Мы должны забиндить *this* явно.
2. Работать не будет, так как `this.context` можно использовать только при наличии проверки *contextTypes*.

**Итого**: мы можем программно перенаправить браузер пользователя на новый URL. Мы научились использовать this.context используя "классический" (от слова "класс") синтаксис ES2015.

[Исходный код](https://github.com/maxfarseer/react-router-ru-tutorial/tree/programming_url_change) на данный момент.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://max-frontend.gitbook.io/react-router-course-ru/podklyuchaem_react-router/programmiruem_perehodi.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
