从 PHP 渲染 React 组件

IT技术 javascript php client-side reactjs
2021-05-25 01:07:48

我正在使用 ReactJS 来支持一个简单的可过滤项目列表,它非常适合我的需要。

问题是,出于 SEO 的原因,我需要在服务器上呈现标记,但是当我调用React.renderComponent(),将现有标记替换为 React 生成的标记。

在 React 的文档中搜索我发现了这个注释:

React.renderComponent() 替换你传入的容器节点的内容。未来,可能可以在不覆盖现有子节点的情况下将组件插入到现有 DOM 节点。

此外,我无法用于React.renderComponentToString()生成标记服务器端,因为我的后端运行在 PHP 上...

当前版本(0.11.2)是否有任何(即使是hackish)方法来实现这一目标?

我想,如果可以使用 renderComponentToString() 生成的标记,那么应该有办法模拟该结果吗?

感谢您的任何建议!

2个回答

你可以看看https://github.com/reactjs/react-php-v8js

它使用 PHP 在服务器端呈现 React UI 组件。

实现非常简单,唯一的要求是您需要能够在您的服务器上设置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 module中。如果他们不是,这是这样做的另一个原因!


我已经几年没有使用过 php,所以如果我犯了任何错误,请更新这个答案。