Я использую ReactJS для включения простого списка фильтруемых элементов, и он отлично работает для моей потребности.
Проблема в том, что мне нужно отображать разметку на сервере по причинам SEO, но когда я вызываю React.renderComponent()
она заменяет существующую разметку тем, что генерируется React.
Поиск в документах React нашел эту заметку:
React.renderComponent () заменяет содержимое узла контейнера, в котором вы проходите. В будущем может быть возможно вставить компонент в существующий узел DOM без перезаписи существующих дочерних элементов.
Кроме того, я не могу использовать React.renderComponentToString()
для генерации серверной части разметки, потому что мой бэкэнд работает на PHP …
Есть ли какой-нибудь (даже хакерский) способ достичь этого с текущей версией (0.11.2)?
Я полагаю, что если это возможно с разметкой, созданной renderComponentToString (), должен быть способ изманить этот результат?
Спасибо за любой совет!
Вы можете посмотреть https://github.com/reactjs/react-php-v8js
Он визуализирует компоненты пользовательского интерфейса на стороне сервера с помощью PHP.
Реализация очень проста, и единственным требованием является то, что вам необходимо настроить расширение V8Js PHP на вашем сервере.
Короткий ответ: не совсем.
Единственный разумный способ сделать это – это запустить процесс узла, с которого php может запрашивать рендер. Это не плохое решение, особенно для страниц, которые сильно кэшируются.
Я предлагаю настроить его очень динамично:
<?php function render_component_to_string($component, $data) { $url = "http://localhost:9000/components/" . $component . "?data=" . rawurlencode(json_encode($data)); return file_get_contents($url) } ?>
<div id="myFilteredList"> <?= render_component_to_string("FilteredList", array("items" => items, "title" => "My List")) ?> </div>
В node.js:
var app = require('express')(); // express@4.x var React = require('react'); // create a dictionary of components // Object.create(null) because the key is supplied var components = Object.create(null); components.FilteredList = require('./components/filtered-list.js'); app.get('/component/:componentName', function(req, res){ var component = components[req.params.componentName]; // safety first! if (!component) { console.error("Invalid component", req.params.componentName); return res.send(404); } // more safety try { var data = JSON.parse(req.query.data); } catch (e) { console.error("Invalid JSON", req.params.componentName, req.query.data); return res.send(400); } // render and send the result back try { var result = React.renderComponentToString(component(data)); } catch (e) { console.error('Could not render', req.params.componentName, 'with props', data); console.error(e.message, '\n', e.stack); return res.send(400); } res.send(result); }); app.listen(9000);
Это, конечно, предполагает, что ваши компоненты находятся в модулях commonjs. Если это не так, это еще одна причина!
Я не использовал php через несколько лет, поэтому, пожалуйста, обновите этот ответ, если я допустил какие-либо ошибки.