Доброго дня! Давайте разберемся.
Достаточно ли просто создать div#catalog и рендерить в него компоненты реакта?
Ответ:
достаточно просто (ссылка на песочницу). Допустим, имеется шаблон (я использовал HTML, но, думаю, с Blade проблем не возникнет):
<html>
<head>
<title>PHP React Test</title>
<script src="https://unpkg.com/react@17/umd/react.production.min.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js" crossorigin></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<?php
$INIT_PARAMS = ['user' => 'Vasilij']; // данные из PHP
echo '<p>Hello React App</p>';
?>
<div id='react-app'></div>
// React-component. Конечно, лучше вынести в отдельный файл, если кода много.
// Еще лучше скомпилировать и подключить минифицированный бандл. Здесь - концептуальный пример.
<script type="text/babel">
'use strict';
const {useState} = React;
function App({user}) {
const [liked, setLiked] = useState(false);
return (
liked ? (`You (${user}) liked this.`) : (
<button onClick={() => setLiked(true)}>
Like
</button>
)
)
}
const domContainer = document.querySelector('#react-app');
ReactDOM.render(<App user={'<?=$INIT_PARAMS['user']?>'}/>, domContainer);
</script>
</body>
</html>
И как быть с SEO в таком случае?
Правильный вопрос. То, что мы сделали выше - называется
"клиентский рендеринг". Для оптимизации SEO он не очень подходит. Такой способ прост, но используется там, где SEO не нужно (например, приложение, в которое в принципе нельзя зайти, не пройдя процедуру авторизации). Для оптимизации SEO используется серверный рендеринг (SSR), а точнее изоморфная структура приложения (совмещаем SSR и CSR). Но поскольку PHP и JS - разные языки, нам потребуется "компилятор JS" прямо в PHP (мы же хотим скомпилировать JS на сервере и отправить клиенту готовый HTML). Для этого можно использовать
V8Js. Почитать подробнее можно, погуглив,
например.
Но, наверное, многие согласятся, что такое использование не типично и крайне усложняет и без того сложный процесс. Если Вы хотите попробовать из академического интереса - я кое-что объяснил. Если же мы говорим про best practice, то давайте разберемся, что Вы хотите:
- Использовать PHP?
- Или использовать React SSR?
- Если Вы хотите использовать PHP и добавить компонентам реактивности, нечто подобное уже реализовано в Laravel: присмотритесь к laravel-livewire или inertiajs. Я бы рекомендовал laravel-livewire. Инструкция по установке того и другого: jetstream Получите архитектуру, почти как в React, только на сервере. Все живое, стэйт обновляется (как? автоматически через скрытые ajax-запросы). Вот, нашел наспех что-то из своего проекта (public $adJob играет роль состояния):
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use Illuminate\Support\Facades\Auth;
class AdJob extends Component {
public $adJob;
public function mount($adJobId) {
$this->adJob = \App\Models\AdJob::find( $adJobId );
}
public function setReleaserForAdJob($releaserId) {
$this->adJob['releaser_id'] = $releaserId;
$this->adJob['status'] = 'in_progress';
$this->adJob->save();
}
public function setAdJobDone() {
$this->adJob['status'] = 'done';
$this->adJob->save();
}
public function render() {
return view('livewire.ad-job-with-reviews');
}
}
И последнее. Если не знакомы с Laravel, но нравится PHP - самое время начать изучать.
- Ежели желаете использовать React - то много проще (чем с PHP) использовать React SSR на Node.js. Самые популярные способы:
- Nextjs, как заметил Андрей Хохлов. Здесь все просто: изучайте документацию по этой технологии.
- React SSR + Express. Здесь, по сути, все то же самое, просто настроить все нужно самому. Хотя, это и более интересно (мне так кажется). Ситуация такова:
Создаем React-приложение на клиенте. Делаем бандл. В пункте 3 будет небольшое дополнение сюда.
На нужных маршрутах на сервере используем
res.send(ReactDOMServer.renderToString(myElement))
- получаем нечто вроде создания "шаблона" (res.send - API express, остальное - react)
На клиенте вместо ReactDOM.render() вызываем ReactDOM.hydrate(element, container), это позволяет не создавать разметку заново, а "гитратировать" HTML, отрендеренный React-ом на сервере и полученный браузером.
Есть также пакеты, позволяющие настроить использование React как шаблонизатора, например: @react-ssr/express. Под капотом он использует тот же renderToString, только с правильной архитектурой и дополнительными, уже настроенными возможностями. В 12-ой строке файла default.tsx из пакета можно увидеть:
const html = ReactDOMServer.renderToString(app);
Таким образом, если интерес для Вас представляет именно PHP - рекомендую Laravel + livewire-компоненты. Если хотите именно React SSR - я бы предпочел Node-стэк (Next или Express+React, вначале сам попробовал бы, потом можно попробовать использовать готовый пакет). Вообще best practice - Next.