从字符串中渲染React组件

时间:2017-05-27 19:51:59

标签: javascript node.js reactjs browser babeljs

我在字符串中有一些React代码,例如:

const component = `
function App() {
  return (
    <div>
    test
    </div>
  );
}
`;

我希望能够在浏览器中呈现该组件,例如:

import React, { Component } from 'react';
import { render } from 'react-dom';
import * as babel from 'babel-standalone';


const babelCode = babel.transform(component, { presets: ['react', 'es2015'] }).code;

render(eval(babelCode), document.getElementById('WorkFlow'));

这个特殊的例子不起作用,但它显示了我正在寻找的东西,任何帮助表示赞赏!

谢谢!

2 个答案:

答案 0 :(得分:1)

React将允许您呈现ComponentElement。您可以将Element视为JSX中的原始HTML代码,而Component是原型,它继承自React.Component。在你的代码中,你试图渲染一个评估babel转换代码的结果,这将失败(我不确定它是什么,但它可能是undefinednull)。如果要使其工作,请首先评估代码,然后调用函数将Element代码传递给render函数:

eval(babelCode);  // now the App function has been defined and you can use it in the code
render(App(), document.getElementById('WorkFlow'));
       // ^^ here the App function is being invoked

旧答案(我以为你试图将component作为文件传递而不是作为变换器传递给转换器):

babel永远不会出现字符串,所以这对你来说不会有用。但是,您可以考虑使用原始JS代码而不是JSX作为字符串内容。有关它的更多信息,请参阅此处:https://facebook.github.io/react/docs/react-without-jsx.html

答案 1 :(得分:1)

Babel使用"use strict"生成代码,而eval()并不能很好地使用它。首先,我们应该手动删除该行。

const code = babelCode.replace('"use strict";', "").trim();

理想情况下,以下行后应该有效。

eval(code);
render(<App/>, document.getElementById('WorkFlow'));

请注意,您不需要将eval()放在渲染中。它不会返回您的应用程序功能或任何东西。相反,它会将App添加到上下文中,我们可以在eval()语句后使用它。

但通常情况下,React app会使用webpack或类似工具进行编译,并会抱怨未定义的App

作为一种解决方法,我们可以用Function包装我们的组件,它返回我们的组件本身。现在我们可以调用这个函数来获取我们的组件。但是包装函数的上下文没有React变量。所以我们必须手动传递它作为参数。如果您要使用当前上下文中的任何其他变量,则还必须传递这些变量。

const code = babelCode.replace('"use strict";', "").trim();
const func = new Function("React", `return ${code}`);
const App = func(React)
render(<App/>, document.getElementById('WorkFlow'));

希望这有帮助!