Когда я начал разрабатывать сайт своего стартапа Windoo, я хотел как можно скорее выйти в Интернет, поэтому выбрал самый безопасный инструмент, который у меня был: Symfony. Backend, frontend, для меня все еще самый удобный универсальный фреймворк. Когда пришло время создавать приложение, я услышал о React Native, поэтому решил перейти на полный гибрид. Итак, у нас был раздел Api в наших контроллерах Symfony, сервисы, в которых все было хорошо!

И тут меня осенило. Я использовал React Native только в приложении, но мало думал о веб-сайте! Поэтому я решил, что мне следует перенести весь сайт в React, а классический сайт Symfony исключить.

Итак, здесь я расскажу о своем путешествии в этот переходный период.

Обновление: какого черта мне вообще понадобилась миграция?

У меня были некоторые отзывы об этой статье (и я благодарю заинтересованных людей), и мне показалось, что я не смог объяснить, почему именно я так сильно пытался перейти на веб-сайт с интерфейсом React. Итак, это основные причины:

Усталость от jQuery. Да, я использую jQuery, и мне это нравится ... для простого эффекта скольжения вверх / вниз. Но для более сложного компонента я устал от спагетти-кода с эффектами onclick, без состояния / шаблонов и сложного управления библиотеками.

СУХОЙ. У меня есть приложение React Native, поэтому для меня было бы немного бесполезно поддерживать интерфейс на основе jQuery, имея в наличии полный набор сервисов в React. Поэтому я планирую создать в конце процесса веб-сайт React и приложение React Native, в котором используются одни и те же основные службы и код, а также просто разные шаблоны для рендеринга.

Шаг 1: создание простого компонента React

Мы начнем с простого: простого компонента.

import React from 'react';
class Checkout extends React.Component {
  render() {
    return (
      <div>
        Hello React !
      </div>
    );
  }
}
export default Checkout;

Затем вставляем его в DOM:

import React from 'react';
import ReactDOM from 'react-dom';
import Checkout from './components/Checkout';
const checkout = document.getElementById('react-checkout-root');
if (checkout) {
  try {
    ReactDOM.render(<Checkout />, checkout);
  } catch (error) {
    console.error(error);
  }
}

И, наконец, загружаем наш шаблон Symfony:

{# AppBundle::Event:show.html.twig #}
{% block body %}
<h1>{{ event.title }}</h1>
<div id="react-checkout-root"></div>
{% endblock %}
{% block javascripts %}
    {{ parent() }}
    {% javascripts 'react-build/js/build.min.js' %}
        <script src="{{ asset_url }}"></script>
    {% endjavascripts %}
{% endblock %}

И вуаля! Теперь на нашей странице Symfony мы загрузили приложение React.

Шаг 2: подключение компонента React к Symfony

Теперь мы хотим, чтобы наш реагирующий компонент учитывал контекст своего местоположения (помните, что на данный момент у нас есть стандартный веб-сайт PHP - Symfony, поэтому статические html-страницы обрабатываются только на стороне сервера). Поэтому, когда я хочу загрузить кассу для события, мне нужны идентификатор события, цена, название и т. Д.… И все это находится в переменной event моей среды twig! Итак, давайте передадим это компоненту, который мы загружаем:

{% block body %}
<h1>{{ event.title }}</h1>
<div
  id="react-checkout-root"
  data-event-id="{{ event.id }}"
  data-event-title="{{ event.title }}"
  data-event-price="{{ event.formattedPrice }}"
></div>
{% endblock %}

Мы собираемся использовать свойство dataset:

import React from 'react';
import ReactDOM from 'react-dom';
import Checkout from './components/Checkout/Checkout';
const checkout = document.getElementById('react-checkout-root');
if (checkout) {
  try {
    ReactDOM.render(
      <Checkout {...(checkout.dataset)}/>,
      checkout
    );
  } catch (error) {
    console.error(error);
  }
}

Итак, теперь наши свойства переданы компоненту, давайте их использовать!

import React from 'react';
class Checkout extends React.Component {
  constructor(props) {
    super(props);
  }
  
  render() {
    return (
      <div>
        <p>
          You want to book our event
          #{this.props.eventId}: {this.props.eventTitle} ?
        </p>
        <p>Price: {this.props.eventPrice}</p>
        <button>Book this !</button>
      </div>
    );
  }
}
export default Checkout;

Легко, правда?

Обратите внимание, как параметры данных, которые я передал в kebab-case и получил взамен мои переменные в CamelCase, приятно для соглашений!

Шаг 3: прибыль!

Теперь, когда у нас настроены наши «глобальные» свойства, у нас есть полностью автономный компонент реакции прямо в середине веб-сайта Symfony! Добавьте состояние, вложенные компоненты и даже немного сети, и готово!

Это было то, что вы могли подготовить миграцию, создав свои основные компоненты и, таким образом, улучшив свой UX, не беспокоясь (пока) о полном переходе на React (потому что вы знаете, маршрутизацию, SEO и прочее…)!

Бонусный шаг: разное.

  • Лично я предпочел передать в качестве параметра только event-id и получить остальную необходимую информацию с помощью запроса ajax, используя axios, как простую, но мощную библиотеку ajax. Да, я понимаю, что могу делать ненужные запросы, но в этом случае мой компонент будет полностью автономным, так что это действительно компонент plug-and-play.
  • Очень мощная вещь, которой я был рад на данный момент, заключалась в том, что файлы cookie сеансов PHP все еще можно использовать, поэтому вся моя аутентификация, выполненная с помощью Symfony, полностью пригодна для использования, не беспокоясь о токенах, что является благословением для новичка в React вроде меня!

Понравилась статья? Пожалуйста, дай мне знать !

Я опубликую свой прогресс на пути к полноценному сайту React.