Reputation: 7593
I found a library I want to use in my project, but it's a plain JavaScript library and doesn't know anything about React.
https://www.npmjs.com/package/json-formatter-js
Is it possible to use this in my React project? I tried this, but the render crashes.
class JSONView extends Component {
constructor(props) {
super(props);
}
render() {
const formatter = new JSONFormatter(this.props.data);
const Rendered = formatter.render();
return (
<div>
<Rendered />
</div>
);
}
}
The error I get is this.
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
The typeof Rendered
is object
.
Upvotes: 0
Views: 74
Reputation: 106
Try this
class JSONView extends React.Component<any, any> {
constructor(props) {
super(props);
}
public refs:{
JsonDiv: HTMLDivElement;
};
componentDidMount(){
const formatter = new JSONFormatter(this.props.data);
this.refs.JsonDiv.appendChild(formatter.render());
}
render() {
return (
<div ref='JsonDiv'>
</div>
);
}
}
or this one
class JSONView extends React.Component<any, any> {
constructor(props) {
super(props);
}
render() {
const formatter = new JSONFormatter(this.props.data);
return (
<div dangerouslySetInnerHTML={formatter.render()}>
</div>
);
}
}
Upvotes: 1
Reputation: 3689
Looks like the library returns HTMLDOMElement
from function formatter.render()
.
So you can't use JSX syntax to render it.
While I agree that the other answers can work, I would prefer using a dom ref
and appending the returned HTMLDOMElement
from formatter.render()
in componentDidMount
lifecycle method.
import React, { Component } from 'react';
import { render } from 'react-dom';
import JSONFormatter from "json-formatter-js";
import Hello from './Hello';
import './style.css';
class JSONView extends Component {
constructor(props) {
super(props);
}
ref = null;
componentDidMount(){
const formatter = new JSONFormatter(this.props.data);
const Rendered = formatter.render();
this.ref.appendChild(Rendered);
}
render() {
return (
<div ref={e => this.ref = e}>
</div>
);
}
}
render(<JSONView data={{Hello: {Hello: "World"}}} />, document.getElementById('root'));
Working Demo You can drill down to the object.
In the other approach which makes use of dangerouslySetInnerHTML or just rendering the string content, you have the risk of losing DOM events.
import React, { Component } from 'react';
import { render } from 'react-dom';
import JSONFormatter from "json-formatter-js";
import Hello from './Hello';
class JSONView extends Component {
constructor(props) {
super(props);
}
ref = null;
render() {
const formatter = new JSONFormatter(this.props.data);
console.log(formatter);
const Rendered = formatter.render();
console.log(Rendered.innerHTML);
return (
<div>
<div dangerouslySetInnerHTML={{__html:Rendered.innerHTML}} />
</div>
);
}
}
render(<JSONView data={{Hello: {Hello: "World"}}} />, document.getElementById('root'));
Working Link You cannot drill down to the object.
Upvotes: 0
Reputation: 367
edit
try
{ Rendered }
there might be warning if it ships class with html tags.
between curly braces {} and it'll work (99 %) and if it doesn't then continue reading.
you can render if it returns string.
currently it might b returning html object which is incompatible with react dom render.
if it contains class property then it'll cause problem even if it's in string format.
you can use react-html-parser to render html strings in react. reference
const Rendered = formatter.render().outerHTML // this will give you html string instead of html object
now use react-html-parser if you don't wanna manage class attribute name conflict as react accepts className
import ReactHtmlParser from 'react-html-parser';
class JSONView extends Component {
constructor(props) {
super(props);
}
render() {
const formatter = new JSONFormatter(this.props.data);
const Rendered = formatter.render().outerHTML;
return (
<div>
{ ReactHtmlParser(Rendered) }
</div>
);
}
}
Upvotes: 0