将一个React元素转换为JSX字符串

44

我正在尝试构建一个组件,该组件:

  1. 接受子元素并
  2. 在DOM中呈现子元素,并且还要
  3. 为文档记录将子元素DOM显示在pre

一种解决方案是将JSX作为单独的prop传递。这使得它重复了,因为我已经能够通过this.props.children访问它。理想情况下,我只需要以某种方式将children prop转换为string,以便我可以在pre中呈现它,以显示"此代码产生此结果"

到目前为止,这就是我的进展

class DocumentationSection extends React.Component{
        render(){
           return <div className="section"> 
                    <h1 className="section__title">{heading || ""}</h1> 
                    <div className="section__body"> {this.props.children}</div>
                    <pre className="section__src">
                        //Change this to produce a JSX string from the elements
                        {this.props.children}
                    </pre>
                </div>;
         }  
}

当我渲染DocumentationSection时,如何获得格式为'<Div className='myDiv'>...</Div>的jsx字符串?

<DocumentationSection heading='Heading 1'>
    <Div className='myDiv'>...</Div>
</DocumentationSection>

谢谢。

编辑:

我尝试了toString,但它没有起作用,显示 [object Object]。


我认为你现在可以选择一个赢家了。 - ADJenks
4个回答

55
如果你想要一个React元素的HTML表示,你可以使用#renderToString#renderToStaticMarkup
import ReactDomServer from 'react-dom/server';

ReactDomServer.renderToString(<div>p</div>);
ReactDomServer.renderToStaticMarkup(<div>p</div>);

将会产生

<div data-reactid=".1" data-react-checksum="-1666119235">p</div>

并且

<div>p</div>

分别。但是您将无法从其内部将父级呈现为字符串。如果您也需要父级,则可以在呈现父级的位置将其renderToString版本作为props传递给自身。


1
嗯,不错。我能够获得HTML表示形式。但是我能否也获得JSX呢?作为字符串的确切props.children元素。 - Bhargav Ponnapalli
不,没有内置的方法可以实现这个功能。但是在Github上有几个项目可以将JSX转换为字符串输出。 - Henrik Andersson
47
自 React 0.14.0 起,React.renderToString 已被弃用,请使用 ReactDomServer.renderToString 替代。 - Luke Willis
11
ReactDOMServer可以这样导入:import ReactDOMServer from 'react-dom/server'; - Daniel

30

React.renderToString 已经弃用,从 React v0.14.0 开始,建议使用 ReactDOMServer.renderToString 代替。

例如:

import ReactDOMServer from 'react-dom/server'
...
ReactDOMServer.renderToString(YourJSXElement())

8
你可以使用react-element-to-jsx-string
import React from 'react';
import reactElementToJSXString from 'react-element-to-jsx-string';

console.log(reactElementToJSXString(<div a="1" b="2">Hello, world!</div>));
// <div
//   a="1"
//   b="2"
// >
//   Hello, world!
// </div>

5

您还可以使用Jest的一部分,也是Jest用于显示JSX断言中差异的pretty-format包。

import React from "react";
import prettyFormat from "pretty-format";
import renderer from 'react-test-renderer';
const { ReactTestComponent } = prettyFormat.plugins;

function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
   </div>
  );
}

console.log(
    prettyFormat(renderer.create(<App />), {
        plugins: [ReactTestComponent],
        printFunctionName: true,
    })
);

这将输出类似以下内容的内容:
<div
  className="App"
>
  <h1>
    Hello CodeSandbox
  </h1>
  <h2>
    Start editing to see some magic happen!
  </h2>
</div>

您可以在这个CodeSandbox上自己尝试: https://codesandbox.io/s/xvxlw370xp

有没有想法如何更改pretty-format的格式,使得<h1>Hello CodeSandbox</h1>显示在一行上?我现在正在使用它,但是当出现新行时,我很难进行格式化。 - wongz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接