【问题标题】:How to render a string with JSX in React如何在 React 中使用 JSX 渲染字符串
【发布时间】:2015-10-21 14:57:58
【问题描述】:

我需要在 React 类中呈现 HTML (JSX) 字符串。我不知道这是否可能。 dangerouslySetInnerHTML 对我无效,因为我在这个文件中有不同的反应组件。它不是纯 HTML。

我有一个预期结果的例子: https://jsfiddle.net/86rg50re/1/

var MyComponent = React.createClass({
    propTypes: {
        owner: React.PropTypes.string
    },

    render: function() {
        return <div>Congrats {this.props.owner}! you have rendered MyComponent ({this.props.children})</div>;
    }
});

var Hello = React.createClass({
    render: function() {
        return <div>Header <MyComponent owner={"Daniel"}>Yayyyyyy!</MyComponent></div>;
    }
});

但我拥有的是这样的:

var Hello = React.createClass({
    render: function() {
        var content = '<div>Header <MyComponent owner={"Daniel"}>Yayyyyyy!</MyComponent></div>';
        return transformStringToJSX(content);
    }

显然 transformStringToJSX 不存在。

有没有办法渲染 jsx 字符串?

【问题讨论】:

  • 您不能像其他导入一样将文件作为 JavaScript 文件导入并从中引用变量和组件吗?
  • 我想这是我最后的选择。我更喜欢另一种选择,因为我只想在该文件中存储 JSX 内容
  • JSX 最终只是 JavaScript。我认为你最好的选择是导出一个瘦包装组件并将其作为 JS 导入。
  • 你的意思是使用这个例如:npmjs.com/package/htmltojsx。然后执行生成的js?
  • 我假设您的意思是编译时未知的 jsx 文件。如果是这样,您可以预编译外部文件而不是将它们作为 jsx 吗?

标签: html reactjs react-jsx


【解决方案1】:

你可以使用 babel 来改造它

npm install --save babel-core

然后在你的代码中

var babel = require('babel-core');
var Component = eval(babel.transform('<div><MyComponent /></div>').code);

请注意,一般是bad idea将字符串转换为可执行代码。

【讨论】:

  • 嗨啊莫尔!它不适用于 babel 包,您必须使用“babel-core”。无论如何,如果我在渲染函数中使用“组件”,它会引发错误。
  • 这与我正在尝试做的事情类似。但不是单个组件,而是包含 JSX 的整个字符串:github.com/facebook/react/issues/3365
  • 如果你使用eval(babel.transform(yourComponentString).code); 它可以工作。但是,我建议不要做你正在尝试做的事情,因为将字符串转换为代码是不好的 JS 做法。
  • @chulian 确保您已指定反应预设。 babeljs.io/docs/plugins/preset-react
  • 然而,评估字符串是大多数模板引擎所做的。
【解决方案2】:

最受好评的答案根本不起作用,跳过了各种关键步骤,并且没有解释代码应该去哪里。我不确定海报是否实际上没有运行代码或什么。无论如何,要真正让它工作,你需要做这样的事情:

npm install @babel/core

npm install @babel/preset-react

您需要使用 babel 将 JSX 转换为可以在服务器端运行客户端的有效 javascript。 next.js中的服务器端代码

export async function getServerSideProps() {
    const stringToRender = require('@babel/core').transform('<h1><Component/></h1>', {presets: ['@babel/preset-react']});
    return {
        props: {
            stringToRender
        }
    }
}

现在我们需要在客户端评估字符串:

import React from 'react';
import Component from '../component'; // Import your component

export default function Page({stringToRender}) {
    const [content, setContent] = useState(null);
    
    useEffect(()=>{
        // It is necessary to evaluate within useEffect and window so that React are available.
        window.Component = Component; // This makes Component defined in the `eval` call.
        setContent(eval(stringToRender))
    }, [])
    
    return (
        <div>
            {content}
        </div>
    )
}

export async function getServerSideProps() {
    const stringToRender = require('@babel/core').transform('<h1><Component/></h1>', {presets: ['@babel/preset-react']});
    return {
        props: {
            stringToRender
        }
    }
}

这段代码实际上会运行到预期的效果。如果您有任何其他要渲染的组件,则需要在 window 对象上单独设置它们,以便在进行 eval() 调用时定义这些组件。

【讨论】:

    猜你喜欢
    • 2020-06-28
    • 2017-09-11
    • 2019-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-17
    • 2017-03-10
    • 2019-08-01
    相关资源
    最近更新 更多