Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Top level element should be a tag or function which returns a tag #3

Open
inspiraller opened this issue Apr 6, 2017 · 4 comments
Open

Comments

@inspiraller
Copy link

Hi
I have installed this plugin but having problems.

$ npm install jsx-to-html

myreactfile.jsx

import React, { Component } from 'react';
import { render } from 'jsx-to-html';

class App extends Component {
	getComp(){
	  	var content = render(<div className="hello">hello</div>);
		console.log('content = ', content);
		return ('<div>hello</div>');
	}
	render() {
    	return (
    		<div className="all">
			{this.getComp()}
		</div>
		)
	}
}

ReactDOM.render(
	<App/>,
	document.getElementById('app')
);

I am getting error:
Uncaught Error: Top level element should be a tag or function which returns a tag

I have tried adding the plugin via .babelrc but that gives me an error too so I'm not entirely sure the plugin has loaded:

.babelrc

{
  "presets" : ["es2015", "react"],
	"plugins": [
 		["jsx-to-html/babel-plugin",
 		{ 
 			"blacklist": ["react"]
 		}]
	]
}
@NekR
Copy link
Member

NekR commented Apr 6, 2017

@inspiraller This plugin was written for Babel 5 and wasn't really intended to be used with React. Why do you even use it?

@inspiraller
Copy link
Author

Jsx is react isn't it? In anycase i want to render my jsx components into a html string so i can escape the tags to becomr pre/code examples before rendering thrm into a documentation page.

The only way i can think to do that currently is render them first into a fragment, then read the innerhtml to escape the tags before rendering it again. I don't like that method because its not as performant.

@SleeplessByte
Copy link

No need for babel or anything else:

import { render } from 'react-dom'

function getReactNodeHtml(node) {
  const detached = document.createElement('div')
  ReactDom.render(node, detached)
  return detached.innerHtml
}

Then use:

const html = getReactNodeHtml((<div className="hello">hello</div>))
console.log(html)

//<div data-reactroot="" class="hello">hello</div>

You probably want to get rid of the data-reactroot attribute:

import { render } from 'react-dom'
const REACT_ROOT_PATTERN = new RegExp(/data-reactroot(?:="")?\s?/)

function getReactNodeHtml(node) {
  const detached = document.createElement('div')
  render(node, detached)
  return detached.innerHtml.replace(REACT_ROOT_PATTERN, '')
}

// <div class="hello">hello</div>

Here is the Typescript without TSX/JSX equivalent

import { render } from 'react-dom'
const REACT_ROOT_PATTERN = new RegExp(/data-reactroot(?:="")?\s?/)

function getReactNodeHtml(node: JSX.Element) {
  const detached = document.createElement('div')
  render(node, detached)
  return detached.innerHTML.replace(REACT_ROOT_PATTERN, '')
}

const html = getReactNodeHtml(createElement('div', { className: 'hello' }, 'hello'))
console.log(html)

// <div class="hello">hello</div>

@inspiraller
Copy link
Author

Thanks. Yes, that is what I am already doing, but as I said I would rather not have to render it first to improve performance. Regards. Thanks for the code example.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants