如何在 React 中使用 JSX 渲染字符串

IT技术 html reactjs react-jsx
2021-04-08 14:01:52

我需要在 React 类中呈现 HTML (JSX) 字符串。我不知道这是否可能。 危险的SetInnerHTML 对我无效,因为我在这个文件中有不同的react组件。它不是普通的 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 字符串?

2个回答

你可以使用 babel 来转换它

npm install --save babel-core

然后在你的代码中

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

请注意,将字符串转换为可执行代码通常是一个坏主意

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

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

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()调用时定义组件