【发布时间】:2021-02-03 14:50:34
【问题描述】:
上下文
我正在尝试将 React 组件转换为 PNG,以便可以将其附加到 Rails 邮件程序中的电子邮件。该组件是一个馅饼Rechart。
我想在 Rails 中完成这一切,而不是使用 Node.js 服务器解决方案,它使用 repng 之类的东西将组件转换为 PNG。
Rechart 将图表组件加载为 SVG,因此我可以访问 SVG 并使用 Mini-Magic 之类的东西将其转换为 PNG。
问题
如何在服务器端将 React 组件加载为 HTML 以便访问 SVG 进行转换。
要在 Rails 中服务器端加载组件,我们可以这样做 what react-rails suggests:
在视图中
<%= react_component('HelloMessage', {name: 'John'}, {prerender: true}) %>
或在控制器中
class TodoController < ApplicationController
def index
@todos = Todo.all
render component: 'TodoList', props: { todos: @todos }, tag: 'span', class: 'todo'
end
end
我想做类似this posts suggests 使用ReactDOMServer 的事情。
// Renders our Hello component into an HTML string
const html = ReactDOMServer.renderToString(<Hello />);
我需要在 Rails 邮件程序中使用 Ruby 进行等效操作。如何以 HTML 格式访问服务器端呈现的组件?
编辑:
sig 的回答是正确的,因为它允许您访问控制器实例的 HTML,这对我有用:
controller_instance = ComponentsController.new()
html_string = controller_instance.render_to_string(:action => "index", :layout => false)
但是,html_string 的输出是:
"<div data-react-class=\"personnel/TrainingStatusChart\" data-react-props=\"{"metaData":{"currentPage":1,"scopedCount":23,"statusGreyCount":15,"statusHighCount":5,"statusLowCount":2,"statusMediumCount":1,"totalCount":23,"totalPages":1,"unscopedCount":23},"prerender":true}\"></div>\n"
它是 React 组件,其中包含所有道具。预渲染 React 组件不会在服务器端将其编译成 HTML。因此,无法访问 React 组件中的 SVG 以转换为 PNG。 This article 表示如下:
此预呈现过程无权访问窗口或文档,因此它不会加载运行时 JavaScript 或 CSS。
我仍然坚信这一定是可能的。也许以某种方式使用 Capybara 和 Headless Chrome 来呈现 React 组件。但是,我还没有找到一个示例实现。
【问题讨论】:
-
它没有渲染整个组件的原因是因为
react_component()实际上并没有在服务器上渲染组件(因为它没有做SSR)。react_component()仅在服务器上呈现最少的必要元素,以便它可以在客户端呈现组件。抱歉,如果这很明显,但只是想确保每个人都在同一页面上。
标签: javascript ruby-on-rails reactjs ruby recharts