Bhargav Ponnapalli
Bhargav Ponnapalli

Reputation: 9412

Convert a React.element to a JSX string

I am trying to build a component which,

  1. Takes children and
  2. Renders the children in the DOM and also,
  3. Shows the children DOM in a pre for documentation sake

One solution is to pass the JSX as a separate prop as well. This makes it repetitive since I am already able to access it through this.props.children. Ideally, I just need to somehow convert the children prop as a string so that I can render it in a pre to show that "this code produces this result".

This is what I have so far

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>;
         }  
}

How can I get the a jsx string in the format '<Div className='myDiv'>...</Div> when I render DocumentationSection as

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

Thanks.

Edit:

I tried toString, it dint work, gave [object Object]

Upvotes: 46

Views: 131385

Answers (4)

Henrik Andersson
Henrik Andersson

Reputation: 47172

If you want the HTML representation of a React element you can use #renderToString or #renderToStaticMarkup.

import ReactDOMServer from 'react-dom/server';

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

will produce

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

and

<div>p</div>

respectively. You will however not be able to render the parent as a string from within itself. If you need the parent too then from where you render the parent pass a renderToString version of it as props to itself.

Upvotes: 61

Charlie Ward
Charlie Ward

Reputation: 411

React.renderToString is depreciated as of React v0.14.0, it's recommended to use ReactDOMServer.renderToString instead.

e.g

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

Upvotes: 31

Fran&#231;ois Zaninotto
Fran&#231;ois Zaninotto

Reputation: 7335

You can also use the pretty-format package, which is part of Jest, and used by Jest to show the diffs in JSX assertions.

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,
    })
);

This will output something like:

<div
  className="App"
>
  <h1>
    Hello CodeSandbox
  </h1>
  <h2>
    Start editing to see some magic happen!
  </h2>
</div>

You can try it by yourself in this CodeSandbox: https://codesandbox.io/s/xvxlw370xp

Upvotes: 5

themouette
themouette

Reputation: 171

You can use 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>

Upvotes: 8

Related Questions