从PHP渲染React组件
问题描述:
我使用ReactJS为一个简单的可过滤项目列表提供支持,它对我的需求非常有效。从PHP渲染React组件
问题是,我需要在服务器上为搜索引擎优化原因呈现标记,但是当我打电话给React.renderComponent()
时,它将使用由React生成的标记替换现有标记。
搜索在阵营的文档,我发现这样一个字条:
React.renderComponent()代替你传递的容器节点的内容在未来,有可能插入组件到现有的。 DOM节点而不覆盖现有的子节点。
而且我不能使用React.renderComponentToString()
,因为我的后端上的PHP运行生成的标记服务器端...
是否有任何(即使hackish的)的方式与当前版本来实现这一( 0.11.2)?
我想,如果renderComponentToString()生成的标记可能会出现这种情况,那么应该有一种方法来模拟该结果?
谢谢你的任何建议!
答
简短的回答是:不是真的。
唯一明智的做法是将一个节点进程运行,哪个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')(); // [email protected]
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,所以如果我犯了什么错误,请更新这个答案。
答
你可以看一下https://github.com/reactjs/react-php-v8js
它使得在服务器端使用PHP反应UI组件。
实现非常简单,唯一的要求是您需要能够在您的服务器上设置V8Js PHP扩展。
感谢您的详细解答!这是一个很酷的解决方案,但我认为这对我的小型需求来说是一种矫枉过正,无论是在复杂性和成本方面(对于Node服务器而言)。如果这是我担心的事情的状态,那么我将不得不重写我的组件,使其能够将其注入到现有的DOM元素中,例如Marionette。无论如何,这真是太糟糕了,我真的很喜欢React :( – Ingro 2014-09-25 23:17:04
除了复杂性之外,你可以在与你的web服务器/ php应用程序相同的服务器/ vps上运行它,这就是它被写入的工作方式(在本地主机上)。 – FakeRainBrigand 2014-09-25 23:28:22
不幸的是,我们没有拥有最终网站上线的网络服务器,所以我们不可能让Node应用程序在其上运行:( – Ingro 2014-09-26 07:31:05